奇怪的线程行为

时间:2017-09-25 05:21:20

标签: c++ c multithreading pthreads mutex

下一个代码通常打印BA,但有时它可以打印BBAA,BAAB,...如何用它获得两个A或B?但是这段代码从不打印三个A或B.两个函数(生成和消费)运行很多线程。非常感谢提前。

int permission;
void set_permission(int v) {
    permission = v;
    printf("%c", v + 'A');fflush(stdin);
}
void* produce(void*) {
    for (;;) {
        pthread_mutex_lock(&mr1);
        set_permission(1);
        while (permission == 1);
        pthread_mutex_unlock(&mr1);
    }
}
void* consume(void*) {
    for (;;) {
        pthread_mutex_lock(&mr2);
        while (permission == 0);
        set_permission(0);
        pthread_mutex_unlock(&mr2);
    }
}

1 个答案:

答案 0 :(得分:4)

您的线程未同步,因为它们没有使用相同的互斥锁。

另一个线程可能只是偶然设置permission为1或0,但尚未设法产生输出。在这种情况下,似乎第一个线程运行了两整轮。

当内核内容在内核之间同步并且两个线程都写入时,相应线程的写入也可以完全丢失。互斥锁还可以防止这种情况发生,因为它建立了一个严格的内存访问顺序,简单来说,它确保在一个互斥锁保护下发生的所有内容对同一个互斥锁的下一个用户完全可见。

打印相同的字符3次或更多次是不太可能的,因为在它们之间最多发生一次写入,因此最多一次丢失写入或一次乱序输出。但这并不能保证。

如果您正在处理一个完全没有隐式内存同步的系统,那么您的代码也可能直接导致死锁,因为在一个互斥锁下执行的写操作永远不会传播给另一个互斥锁的用户。 (实际上并不是因为IO操作引入了一些同步。)