使用bool全局变量进行线程同步(Thread syncronization by using bool global variable)

我知道这个问题看起来可能与现有的问题类似,但我找不到有用的建议。 我正在编写一个C程序,其中包括两个线程,一个发送消息,另一个检查对消息的回复。 我希望发送消息的线程停止,直到接收线程变为true,这是一个bool变量,表明发送消息中包含的请求已被满足。 我写了这种类型的代码。 对于发送线程:

executed = false; function_to_send_the_message(); while(!executed);

对于接收线程:

msg = function_to_receive_the_message(); if(msg->good){ status = pthread_mutex_lock(&mutex); assert(status == 0); executed = true; printf("Executed order!\n"); pthread_mutex_unlock(&mutex); assert(status == 0); }

互斥体是一个全局变量。 这是一个简化的代码,所以不要看一些奇怪的陈述。 关键是发送线程在while循环中被阻塞,并且不会继续。 我不知道是否以及如何在while循环中添加互斥锁。 感谢您的任何建议。

I know that this question can seem similar to already existing ones, but I couldn't find a useful suggestion. I am writing a C program consisting of, among the other things, two threads, one sending a message and the other checking the reply to the message. I would like that the thread sending the message stop till the receiving thread turn to true a bool variable suggesting that requests contained in the sending message has been satisfied. I wrote a code of this type. For the sending thread:

executed = false; function_to_send_the_message(); while(!executed);

For the receiving thread:

msg = function_to_receive_the_message(); if(msg->good){ status = pthread_mutex_lock(&mutex); assert(status == 0); executed = true; printf("Executed order!\n"); pthread_mutex_unlock(&mutex); assert(status == 0); }

The mutex is a global variable. This is a simplified code, so don't look at some weird statements. The point is that the sending thread is blocked in the while loop and doesn't go ahead. I don't know if and how I have to put a mutex also in the while loop. Thanks for any suggestion.

最满意答案

在你的发送线程中,循环

while(!executed);

通过编译器进行优化

some_register = !executed; while(some_register);

因为据它所知, executed的值不能在循环条件的测试之间改变(毕竟循环体是空的)。

通常建议的方法是通过让互斥锁保护每个对此变量的读/写,如下所示:

temp = true; while(temp){ mutex_lock(m); temp = !executed; mutex_unlock(m); }

或者对于这种情况更好一个条件变量。 这些结构会导致“内存障碍”,这就意味着访问互斥之前加载到寄存器中的变量将被假定为陈旧并在使用后重新加载。

另一种经常被滥用但在某些情况下可能是正确方法的方法是声明executed为volatile 。 这会导致只有这个变量的每个读/写都会一直到达内存,而不是使用缓存的寄存器。

In your sending thread, the loop

while(!executed);

gets optimized by the compiler to something like

some_register = !executed; while(some_register);

since as far as it can tell, the value of executed can't change between tests of the loop condition (the loop body is empty, after all).

The usually suggested way to solve this is by having a mutex protect each read/write to this variable, like this:

temp = true; while(temp){ mutex_lock(m); temp = !executed; mutex_unlock(m); }

or even better for this case, a condition variable. These constructs cause "memory barriers", which simply put means that variables that were loaded into registers before accessing a mutex will be assumed stale and reloaded after using it.

Another approach that is often misused but can be a correct approach in certain cases is to declare executed as volatile. This causes every read/rite of only this variable to go all the way to the memory and not used cached registers.

更多推荐