【问题标题】:Im new to threads and semaphores and i can seem to understand why my code wont work, any help will be appreciated我是线程和信号量的新手,我似乎可以理解为什么我的代码不起作用,任何帮助将不胜感激
【发布时间】:2019-06-15 12:40:42
【问题描述】:

我正在尝试编写一个使用信号量打印 的代码,但该代码无法运行,而且我找不到我的错误。

我也试过pthread_join,但还是一样:无论如何都不会打印。

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <semaphore.h>

sem_t f1, f2, f3;

int done = 1;

void *threadfunc(void *n) {
    int a = 0;

    while (1) {
        if ((int)*(int *)n == 1) {
            //printf("1st THREAD!\n");
            printf("<ONE>");
            sem_wait(&f1);
        } else if ((int)*(int *)n == 2) {
            //printf("2st THREAD!\n");
            printf("<TWO>");
            sem_wait(&f2);
        } else {
            //printf("3st THREAD!\n");
            printf("<THREE>");
            sem_wait(&f3);
        }

        //}

        if (done == 3) {
            done = 1;
            sem_post(&f1);
        } else if (done == 1) {
            done = 2;
            sem_post(&f2);
        } else if (done == 2) {
            done = 3;
            sem_post(&f3);
        }
    }
}

int main() {
    pthread_t tid1, tid2, tid3;
    int n1 = 1, n2 = 2, n3 = 3;

    for (;;) {
        // Create 3 threads
        pthread_create(&tid1, NULL, threadfunc, (void *)&n1);
        sleep(1);

        pthread_create(&tid2, NULL, threadfunc, (void *)&n2);
        sleep(1);

        pthread_create(&tid3, NULL, threadfunc, (void *)&n3);
        sleep(1);

        // infinite loop to avoid exit of a program/process
    }

    return 0;
}

预期输出:ONE TWO THREE ONE TWO THREE

实际输出:无

【问题讨论】:

  • 您不断创建线程而不是仅仅创建 3 个线程,所以也许考虑删除 'for(;;)' 并在 main 中为每个线程使用 pthread_join(tidx, NULL);
  • 您可能希望在创建线程之前使用sem_init 初始化您的信号量。
  • 你能告诉我如何初始化信号量吗,因为我是新手,我不知道该怎么做,提前谢谢。
  • "我是新手" 阅读相关文档怎么样,例如man sem_init?

标签: c multithreading semaphore


【解决方案1】:

您的代码中有多个问题:

  • 您不仅启动了三个线程,而且启动了无数个线程。您代码中的注释表明这样做的目的可能是防止主线程退出,但这是解决问题的完全不合适的方法。通常的方法是 pthread_join() 你的线程,或者可能只是 sigsuspend()pause()

  • 您使用信号量而不初始化它们。因此,所有信号量函数的行为都是未定义的。您必须在程序开始时使用sem_init() 来初始化每个信号量的状态,包括但不限于其初始值。可能其中一个应该用值 1 初始化,而其他的应该用值 0 初始化。

  • 你的线程函数的结构很奇怪。通常,等待信号量首先,然后做任何工作,然后最后发布下一个信号量。但是,即使您按照自己的方式安排信号量操作,我也认为变量done 没有任何意义。您对 n 的使用完全是多余的。两者传达相同的信息:线程的身份。

  • 如果你想让每个线程打印的数据立即出现,那么你应该在每次printf()调用之后fflush(stdout)

  • 如果你想要打印之间的延迟,那么你应该把它放在线程函数中,而不是 main()

【讨论】:

    猜你喜欢
    • 2021-05-11
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 2021-10-29
    相关资源
    最近更新 更多