pthread_join()并在main中睡觉

时间:2013-10-16 11:29:48

标签: c linux multithreading pthreads posix

我有一个程序可以创建两个工作线程,如下所示:

void *Producer(void *threadarg){
    while (!terminate_producer){ //do something}
    printf("Producer: finalizing thread\n");
    pthread_exit(NULL);
}

void *Consumer(void *threadarg){
    while (!terminate_consumer){ //do something}
    printf("Consumer: finalizing thread\n");
    pthread_exit(NULL);
}

// Initialize array of the worker threads
void initFuncArray(long result[])
{
    result[0] = (long)&Producer;
    result[1] = (long)&Consumer;
}

// The main method
int main (int argc, char* argv[]){
    long th_funcs[CPUS_NUM];
    initFuncArray(th_funcs);
    // threads data
    pthread_t tid[CPUS_NUM];
    thread_data prod_th_data[CPUS_NUM];
    bool pt = false;
    for (int i=0;i<CPUS_NUM;i++){
        prod_th_data[i].thread_id = i;
        pt = pthread_create(&tid[i], NULL, (void *)th_funcs[i], (void*)&prod_th_data[i]);
        if (pt) return -1;
    }
    sleep(5);
    terminate_producer = true;
    pthread_join (tid[0], NULL);
    **sleep(1);**
    terminate_consumer = true;
    pthread_join (tid[1], NULL);

    // Exiting the main thread
    return 0;
}

我的问题是关于在终止消费者线程之前调用sleep。如果我没有这个电话,程序将正常终止。但是,如果我有睡眠,程序永远不会终止。我看到生产者线程终止的消息,但我没有从消费者线程获得消息。可能是什么问题?

以下建议我修改了如下代码,但是,即使没有调用睡眠,问题现在也出现了:

typedef void (*func_type) (void *);
pthread_mutex_t terminate_producer;
pthread_mutex_t terminate_consumer;

void *Producer(void *threadarg){
    while (pthread_mutex_trylock(&terminate_producer)){ //do something}
    printf("Producer: finalizing thread\n");
    pthread_mutex_unlock(&terminate_producer);
    return NULL;
}

void *Consumer(void *threadarg){
    while (pthread_mutex_trylock(&terminate_consumer))
    printf("Consumer: finalizing thread\n");
    pthread_mutex_unlock(&terminate_consumer);
    return NULL;
}

// Initialize array of the worker threads
void initFuncArray(func_type result[])
{
    result[0] = Producer;
    result[1] = Consumer;
}

// The main method
int main (int argc, char* argv[]){
    func_type th_funcs[CPUS_NUM];
    initFuncArray(th_funcs);
    // threads data
    pthread_t tid[CPUS_NUM];
    thread_data prod_th_data[CPUS_NUM];

    // Using mutexes as termination condition
    pthread_mutex_init(&terminate_producer,NULL);
    pthread_mutex_init(&terminate_consumer,NULL);
    pthread_mutex_lock(&terminate_producer);
    pthread_mutex_lock(&terminate_consumer);

    bool pt = false;
    for (int i=0;i<CPUS_NUM;i++){
        prod_th_data[i].thread_id = i;
        pt = pthread_create(&tid[i], NULL, (void *)th_funcs[i], (void*)&prod_th_data[i]);
        if (pt) return -1;
    }
    sleep(5);
    pthread_mutex_unlock(&terminate_producer);
    pthread_join (tid[0], NULL);

    pthread_mutex_unlock(&terminate_consumer);
    pthread_join (tid[1], NULL);

    // Exiting the main thread
    return 0;
}

2 个答案:

答案 0 :(得分:2)

标志terminate_producer代表一个关键部分。生产者正在阅读它的价值,主线程同时重写它。应使用某些同步机制(如mutex:

)保护对此标志的访问
inline stopProducers() {
    /* GET LOCK */
    terminate_producer = 1;
    /* RELEASE LOCK */
}

inline unsigned char shouldProduce() {
    unsigned char terminate = 0;
    /* GET LOCK */
    terminate = terminate_producer;
    /* RELEASE LOCK */
    return !terminate;
}

void *Producer(void *threadarg){
    while (shouldProduce()){ /* do something */ }
    printf("Producer: finalizing thread\n");
    return NULL;  // <-- use return instead of pthread_exit
}

并在main中,您可以调用stopProducers();而不是重写标记;

答案 1 :(得分:2)

这可能是由于编译器启发式地总结(作为优化),terminate_consumer是一个仅在消费者线程中读取的变量,因此它将它“缓存”在寄存器中并且永远不会读取它。

您可以将terminate_producer和terminate_consumer的声明更改为:

volatile int terminate_producer;
volatile int terminate_consumer;

..再试一次?