pthreads等待和信号疑问linux

Posted

技术标签:

【中文标题】pthreads等待和信号疑问linux【英文标题】:pthreads wait and signal doubts linux 【发布时间】:2012-07-27 06:30:22 【问题描述】:

在 pthread 等待之前,我们使用互斥锁进行锁定,这样其他代码可能不会尝试更改条件变量。 wait 然后解锁互斥体并等待信号。

说,在其他一些线程中,我锁定了同一个互斥体,之后,我使用了“信号”。然后解锁线程。 当信号完成时,等待线程唤醒并再次获取互斥锁。

Thread1                   Thread2
                         
    lock(mutex);               lock(mutex);
    wait(mutex);               signal(mutex);
    unlock(mutex);             unlock(mutex);
                          

假设三个线程一语句包含在 while(1) 循环中。然后假设 thread2 锁定互斥体,向它发出信号,然后解锁互斥体。然后没有结束,而是进入睡眠状态。

那么条件变量的值会永久改变吗?如果线程一的三个语句在无限循环中运行,它会不会永远等待,只是发现信号已经发出?等待调用返回时,是否将条件变量的值设置回初始值?

如果是,我可以对变量使用创建、销毁或初始化方法来设置值吗?如果是,如何?这些函数具体是做什么的?

谢谢,

【问题讨论】:

【参考方案1】:

pthread_cond_signal() 将始终唤醒至少一个当前 等待pthread_cond_wait() 中的条件变量的线程。如果同一个线程或不同的线程再次调用pthread_cond_wait(),它将阻塞并等待另一个信号。

这意味着 pthread 条件变量必须始终与某种共享数据配对,由调用 pthread_cond_wait() 时持有的互斥锁保护。在调用pthread_cond_wait()之前,线程必须检查共享数据以查看它想要等待的条件是否已经发生——如果没有,它不应该等待。

此类共享数据的最简单示例可能是全局标志。在您的示例中:

int flag = 0;

Thread 1 
    pthread_mutex_lock(&mutex);
    while (!flag)
        pthread_cond_wait(&cond, &mutex);
    pthread_mutex_unlock(&mutex);


Thread 2 
    pthread_mutex_lock(&mutex);
    flag = 1;
    pthread_mutex_signal(&cond);
    pthread_mutex_unlock(&mutex);

您可以在此处看到,当条件为“重置”时完全在您的控制之下 - 例如,您可以在调用 pthread_mutex_unlock() 之前将 Thread 1 设置为 flag = 0;

共享状态通常比简单的标志更复杂 - 例如,您可能有一个生产者线程调用pthread_mutex_wait(),而共享缓冲区中没有空间。

【讨论】:

在你的例子中,在第二个线程“信号”之后,还写了一些其他语句。在线程 2 发出信号后,线程 1 被唤醒并将互斥锁分配给该线程 1。第二个线程是否进入睡眠状态?并且在互斥锁被释放后它是否会唤醒(可能会或可能不会取决于这次谁获得了互斥锁)? 1) 线程 1 获取互斥锁。检查标志,标志为0。进入while。等待语句解锁互斥锁,之后线程是否进入睡眠状态?如果是,while循环有什么用?因为只有在 flag 设置为 1 之后才会唤醒它。 if 语句可能更有意义。或者如果不存在任何语句,则等待语句只是解除互斥锁并等待信号。怎么了>? 2) 线程 2 获取互斥锁。将 flag 设置为 1 并发出信号。 (假设 thread1 现在处于等待状态)。那么在发出信号之后,这个thread2现在是否进入睡眠状态?当互斥量释放时,它是否会醒来为互斥量而战? 另外,假设我一次又一次地运行线程 2 中的语句(在某种循环中),一次又一次地给出信号。但是会有一段时间 thread1 到达它的等待语句。在那个时间点,之前的信号会影响这个等待还是这个等待完全来自不同的角度?即,下一次信号由线程 2 给出,线程 1 唤醒,就好像在它之前没有产生信号一样 @neeraj:pthread_cond_wait() 原子地解锁互斥体并使进程进入睡眠状态。当线程 2 发出条件变量信号时,线程 1 将唤醒并继续,直到线程 2 解锁互斥锁(pthread_cond_signal() 不会阻塞)。如果当时没有线程在条件变量上等待,pthread_cond_signal() 什么也不做(这就是为什么你需要在调用pthread_cond_wait() 之前测试标志的值)。

以上是关于pthreads等待和信号疑问linux的主要内容,如果未能解决你的问题,请参考以下文章

pthread_join - 多个线程等待

如何为 3 个不同的事件(信号量、pthread 条件和阻塞套接字接收)阻塞单个线程?

使用 pthread 时无法捕获 SIGINT 信号

读者线程没有退出 - Posix Pthreads

线程同步信号量system v IPC

条件变量信号