有点奇怪。我的情景如下:
在文件A.c中定义两个全局变量:
volatile bool g_test = true;
pthread_mutex_t g_test_mutex = PTHREAD_MUTEX_INITIALIZER;
在文件A.c中,全局变量是只读的。
...
pthread_mutex_lock(& g_test_mutex);
if(! g_test){
ret = -1;
pthread_mutex_unlock(& g_test_mutex);
goto cleanup;
}
pthread_mutex_unlock(& g_test_mutex);
...
并将全局变量写入另一个文件B.c
...
extern volatile bool g_test;
extern pthread_mutex_t g_test_mutex;
bool tmpval = func_to_getval();
if(tmpval != g_test){
pthread_mutex_lock(& g_test_mutex);
g_test = tmpval;
pthread_mutex_unlock(&g_test_mutex);
}
printf("g_test value:%s\n",g_test?"yes":"no");
...
以上代码都可以。
但删除最后一个printf语句时很奇怪,当g_test发生更改且文件A.c无法获取更新值时,无法成功同步该值。为什么?
更新
我更改了代码:
bool tmpval = func_to_getval();
if(tmpval != g_test){
pthread_mutex_lock(& g_test_mutex);
g_test = tmpval;
pthread_mutex_unlock(&g_test_mutex);
}
printf("g_test value:%s\n",g_test?"yes":"no");
到
pthread_mutex_lock(&g_can_encrypted_mutex);
g_can_decrypted = func_to_getval(env);
pthread_mutex_unlock(&g_can_encrypted_mutex);
它通过了。但是每次都会锁定互斥锁,使用这种方法会增加多少费用?
答案 0 :(得分:1)
B.c不应该在没有持有g_test_mutex的情况下引用g_test;两个线程可以争夺这个代码,因为你在if中读取了g_test,然后在以后更新它,另一个线程可能会在此期间进入并更新g_test。
这意味着这个原始代码是错误的:
from tkinter import*
import tkinter.messagebox
root = Tk()
def func(label):
tkinter.messagebox.askquestion("Information", "you have selected: ", label )
mymenu = Menu(root)
root.config(menu = mymenu)
submenu = Menu(mymenu)
mymenu.add_cascade(label = "file", menu = submenu)
submenu.add_command(label ="project", command = func)
submenu.add_command(label = "save", command = func)
submenu.add_separator()
submenu.add_command(label ="exit", command = func)
root.mainloop()
您应该在保存锁定时分配的局部变量中保留g_test的副本;然后在释放锁之后,在printf()中使用该局部。
当并发程序通过改变通信区域之外的时间来改变行为时,请寻找竞争条件。
答案 1 :(得分:0)
您的计划在printf
通话后很快就会结束吗?您在main
的末尾附近显示为B.c的代码,或者exit
之后调用printf
或类似的代码?如果是这样,那么您的程序可能会在A.c中的代码运行之前终止,并且对printf
的调用只会延迟退出足够长的时间以使其有时间运行。如果是这种情况,您需要添加一些退出同步 - 例如,调用pthread_join
。