基本的Mutex导致程序锁定在C中

时间:2013-11-04 18:08:26

标签: c multithreading pthreads mutex

我有一个简单的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);
        }
}

2 个答案:

答案 0 :(得分: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()可能会在你的thread_1_start()读取任何内容之前多次打印passedChar

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

你可能想要的是:

  • 主题A:阅读2个字符
  • 线程A:信号线B表示有2个字符要处理
  • 线程A:等到线程B处理完2个字符。

  • 线程B:等待线程A表示有2个字符要处理

  • 线程B:处理2个字符
  • 线程B:我们已完成处理的信号线程

答案 1 :(得分:0)

当线程1到达此行时,

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

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