0

我有一个简单的 C 程序,它使用互斥体从一个线程的标准输入中收集一个字符,然后在另一个线程上打印出来。两个线程都正确启动(下面的 printf 表示线程开始运行),但是自从我引入 Mutex' 以来,这两个线程都没有运行。有谁知道为什么?(我在我的 char 数组中收集了两个字符,因为我也在收集返回字符。)

谢谢!

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

struct thread_info {    /* Used as argument to thread_start() */
        pthread_t thread_id;/* ID returned by pthread_create() */
        char passedChar[2];
        pthread_mutex_t passedCharMutex;
        pthread_cond_t conditionalSignal;
};

static void *thread_1_start(void *arg) {
        struct thread_info *myInfo = arg;
        printf("Started thread id: %d\n", myInfo->thread_id);
        while (1) {
                printf("thread1 while ran");
                pthread_mutex_lock(&myInfo->passedCharMutex);
                int rid = read(0,myInfo->passedChar,2);
                pthread_mutex_unlock(&myInfo->passedCharMutex);
        }
        pthread_exit(0);
}

int main() {
        struct thread_info tinfo;
        printf("Main thread id: %d\n", tinfo.thread_id);

        int s = pthread_create(&tinfo.thread_id,
                NULL, // was address of attr, error as this was not initialised.
                &thread_1_start,
                &tinfo);
        pthread_join(tinfo.thread_id,NULL);

        while (1) {
                printf("thread2 while ran");
                pthread_mutex_lock(&tinfo.passedCharMutex);
                write(1,tinfo.passedChar,2);
                pthread_mutex_unlock(&tinfo.passedCharMutex);
        }
}
4

2 回答 2

1

pthread_mutex_t 和 pthread_cond_t 必须先初始化,然后才能使用它们。

struct thread_info tinfo;
pthread_mutex_init(&tinfo.passedCharMutex, NULL);
pthread_cond_init(&tinfo.conditionalSignal, NULL);

tinfo在这种情况下,您也可以在初始化变量时初始化它们:

struct thread_info tinfo = {
     .passedCharMutex  = PTHREAD_MUTEX_INITIALIZER,
     .conditionalSignal = PTHREAD_COND_INITIALIZER
};

你还有一个

 pthread_join(tinfo.thread_id,NULL);

创建第一个线程后,这将导致您等到线程结束,因为 thread_1_start() 运行无限循环,所以它永远不会这样做 - 您永远不会到达 main() 中的 while 循环。

虽然不是您问题的一部分,但还有其他问题:

你的两个线程的逻辑没有同步。就目前而言,它们都在不考虑彼此的情况下运行,因此您的 main() 可能会passedChar在您的 thread_1_start() 读取任何内容之前打印出很多次。

同样,thread_1_start() 可能会在您的 main() 线程有机会打印之前读取大量数据。

你可能想要的是:

  • 线程 A:读取 2 个字符
  • 线程 A:通知线程 B 有 2 个字符要处理
  • 线程 A:等到线程 B 处理完 2 个字符。

  • 线程 B:等待线程 A 发出有 2 个字符要处理的信号

  • 线程 B:处理 2 个字符
  • 线程 B:向线程 A 发出信号,表明我们已经完成了进程
于 2013-11-04T20:56:01.140 回答
0

当线程 1 来到这一行时,

int rid = read(0,myInfo->passedChar,2);

它持有锁,然后阻止输入。Tread 2 等待线程 1 退出。如果没有输入,任何线程都不会取得进展。

于 2013-11-04T20:36:54.353 回答