【问题标题】:Pthread synchronization - print even odd numbersPthread 同步 - 打印偶数奇数
【发布时间】:2018-08-22 21:59:05
【问题描述】:

我是 pthreads 的新手。我正在尝试从两个线程打印偶数和奇数。下面的代码有什么问题?它的目的是创建两个线程——一个打印奇数,另一个打印偶数。数字必须按顺序打印。它似乎卡住了(ideone中超过了时间限制)..我花了很多时间盯着它。就是想不通怎么回事。。

#include <stdio.h>
#include <pthread.h>


pthread_mutex_t lock;
int n = 0;
int max = 10;

pthread_cond_t even;
pthread_cond_t odd;


void* print_odd(void *x)
{
    while(1)
    {
        pthread_mutex_lock(&lock);
        while(n%2 != 0)
        {
            pthread_cond_wait(&even, &lock);
        }
        if(n >= max)
        {
            pthread_mutex_unlock(&lock);
            pthread_exit(NULL);
        }
        printf("Thread A : %d", ++n);
        pthread_cond_signal(&odd);
        pthread_mutex_unlock(&lock);
    }
}


void* print_even(void *x)
{
    while(1)
    {
        pthread_mutex_lock(&lock);
        while(n%2 == 0)
        {
            pthread_cond_wait(&odd, &lock);
        }
        if(n >= max)
        {
            pthread_mutex_unlock(&lock);
            pthread_exit(NULL);
        }
        printf("Thread B : %d", ++n);
        pthread_cond_signal(&even);
        pthread_mutex_unlock(&lock);
    }
}

main()
{
    pthread_t t1, t2;
    pthread_create(&t1, NULL, print_odd, NULL);
    pthread_create(&t2, NULL, print_even, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    exit(0);
}

【问题讨论】:

  • 您需要初始化互斥锁和条件变量。参见例如this question

标签: c multithreading pthreads mutex


【解决方案1】:

您的程序存在多个问题-

  1. 根据 cmets 的建议,lock 和条件变量需要初始化。
pthread_mutex_t lock = PTHREAD_LOCK_INITIALIZER;
pthread_cond_t  even = PTHREAD_COND_INITIALIZER;
pthread_cond_t  odd =  PTHREAD_COND_INITIALIZER;

即使没有初始化,您也可能会在这里意外幸运,因为您已将它们声明为全局并且它们将是零初始化的,而当您正确初始化它们时,pthread 实现实际上可能是零初始化的。

  1. 您的printf 没有\n,因此输出不会刷新到屏幕。只需添加换行符,您就会看到您的线程确实在运行。

  2. n 达到10 时,即当print_odd 线程从9 递增时,它会简单地退出而不发出偶数线程的信号。因此,您的偶数线程挂在cond_wait 中,而您的main 线程挂在pthread_join 中。您可以通过在退出奇数线程之前发出信号来唤醒偶数线程来解决此问题。

编辑我又发现了一个问题

  1. 即使奇数线程在退出之前发出偶数线程的信号,由于n=10,偶数线程不会退出while(n%2 == 0) 循环并再次进入睡眠状态。这一次,没有人唤醒可怜的灵魂。正是出于这个原因,您需要在while 循环内测试终止条件n&gt;=max

【讨论】:

  • 感谢您的宝贵时间。
【解决方案2】:

pthread_cond_wait 正在阻塞调用线程。在您的情况下,您已要求线程等待奇数和偶数的 true 条件。相反,他们应该等待不正确条件。

  • 虽然i%2 == 0odd 线程应该调用例程内部的等待函数。
  • i!=2 时,even 线程应该调用等待函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多