下一个代码通常会打印 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);
}
}
最佳答案
您的线程未同步,因为它们未使用相同的互斥量。
另一个线程偶然只能设法将 permission
设置为 1 或 0,但尚未设法产生输出。在这种情况下,第一个线程似乎运行了两整轮。
当内存内容在内核和两个线程写入之间同步时,相应线程的写入也可能完全丢失。互斥体也可以防止这种情况发生,因为它建立了严格的内存访问顺序,简单来说,保证了在一个互斥体保护下发生的一切对同一互斥体的下一个用户是完全可见的。
打印同一个字符 3 次或更多次的可能性很小,因为中间最多发生一次写入,因此最多一次丢失写入,或者一次乱序输出。但这并不能保证。
如果您在一个根本没有隐式内存同步的系统上工作,您的代码也可能直接死锁,因为在一个互斥体下完成的写入永远不会传播到另一个互斥体的用户。 (实际上并没有发生,因为 IO 操作仍然引入了一些同步。)
关于c++ - 奇怪的线程行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46398068/