简体   繁体   English

pthread互斥锁在while(1)中锁定/解锁

[英]pthread mutex lock/unlock in while(1)

I'm trying to write very simple multi threading program just to get the catch of it but I fail to understand what exactly is wrong in one of the cases. 我试图编写一个非常简单的多线程程序只是为了抓住它,但是我无法理解在其中一种情况下到底是什么错误。 So: 所以:

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

char string[100];
pthread_t thr_id_rd;
pthread_t thr_id_wr;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond, cond1;
int read = 0;

void *thread_rd()
{
    pthread_mutex_lock(&lock);
    while (1) {
        pthread_cond_wait(&cond, &lock);
        printf("rd: entered: %s\n", string);
        pthread_cond_signal(&cond1);
    }
    pthread_mutex_unlock(&lock);
}

void *thread_wr()
{
    pthread_mutex_lock(&lock);
    while (1) {
        printf("wr: enter something: ");
        scanf("%s", string);
        pthread_cond_signal(&cond);
        pthread_cond_wait(&cond1, &lock);
    }
    pthread_mutex_unlock(&lock);
}

int main(int argc, char *argv[])
{
    pthread_create(&thr_id_rd, NULL, thread_rd, NULL);
    pthread_create(&thr_id_wr, NULL, thread_wr, NULL);

    pthread_join(thr_id_rd, NULL);
    pthread_join(thr_id_wr, NULL);

    return 0;
}

The above seems to work correctly. 以上似乎正常工作。 But when I edit the two threads like this: 但是当我像这样编辑两个线程时:

void *thread_rd()
{
    while (1) {
        pthread_mutex_lock(&lock);
        pthread_cond_wait(&cond, &lock);
        printf("rd: entered: %s\n", string);
        pthread_cond_signal(&cond1);
        pthread_mutex_unlock(&lock);
    }
}

void *thread_wr()
{
    while (1) {
        pthread_mutex_lock(&lock);
        printf("wr: enter something: ");
        scanf("%s", string);
        pthread_cond_signal(&cond);
        pthread_cond_wait(&cond1, &lock);
        pthread_mutex_unlock(&lock);
    }
}

I'm getting undefined behavior - sometimes it's OK sometimes the program is stuck. 我得到不确定的行为-有时没问题,有时程序被卡住。 According the man pages pthread_cond_wait must be called with mutex locked but there is no such restriction for _cond_signal (Question: What is the best practice?). 根据手册页, 必须在锁定互斥锁的情况下调用pthread_cond_wait,但是_cond_signal没有这样的限制(问题:最佳实践是什么?)。 So I decided to call it with mutex locked... 所以我决定将其锁定为互斥锁...

Obviously I'm complete newbie so please excuse my stupid question :( I'll be very grateful if someone can explain this to me... 显然我是新手,所以请原谅我的愚蠢问题:(如果有人可以向我解释这个问题,我将不胜感激...

pthread conditional variable signals are not persistent. pthread条件变量信号不是持久性的。 If you signal when nothing is waiting for the signal, the signal will be lost. 如果没有信号等待信号时发出信号,信号将丢失。 So you could see something like this: 这样您可以看到类似以下内容的内容:

WR: Lock
WR: Read input
WR: Signal cond
WR: Wait for cond1 (implicitly unlocks)
RD: Lock
RD: Wait for cond (implicitly unlocks)

At this point you have a deadlock - both threads are waiting for signals which will never come. 此时,您将陷入僵局-两个线程都在等待永远不会到来的信号。

The usual pattern with condvars is to have a flag (or some other persistent condition) paired with the conditional variable. condvars的通常模式是将一个标志(或其他一些持久条件)与条件变量配对。 You can then do a loop like: 然后,您可以执行如下循环:

while (!flag) pthread_cond_wait(&cond, &lock);

To signal, you set the flag, and then signal the condvar to wake up any waiters. 要发出信号,请设置该标志,然后向condvar发出信号以唤醒任何侍者。

In your case you can actually use string as your flag - have string == NULL be the wake-up condition paired with cond1 and string != NULL paired with cond . 在您的情况下,您实际上可以使用string作为标记-将string == NULLcond1配对作为唤醒条件, cond1 string != NULLcond配对配对。 Now if your reader thread enters the lock late it'll see that string != NULL and not wait on the condvar. 现在,如果您的阅读器线程进入锁的时间较晚,它将看到string != NULL而不必等待condvar。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM