【问题标题】:pthreads wait and signal doubts linuxpthreads等待和信号疑问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 锁定互斥体,向它发出信号,然后解锁互斥体。然后没有结束,而是进入睡眠状态。

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

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

谢谢,

【问题讨论】:

    标签: pthreads signals wait


    【解决方案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() 之前测试标志的值)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    相关资源
    最近更新 更多