以下是我的线程学习测试代码:
int mylock = 0;
void *r1(void *x)
{
puts("entered r1");
int *p;
p = (int *)x;
int i = *p;
sleep(1);
*p = --i;
printf("r1: %d\n",*p);
mylock = 1;
printf("r1: done\n");
#ifdef USETHREADS
pthread_exit(0);
#endif
}
void *r2(void *x)
{
puts("entered r2");
if (!mylock) {
puts("r2 is waiting...");
while (!mylock)
printf("");
}
int *p;
p = (int *)x;
int i = *p;
*p = ++i;
sleep(1);
printf("r2: %d\n",*p);
printf("r2: done\n");
#ifdef USETHREADS
pthread_exit(0);
#endif
}
main()
{
int i1,i2;
i1 = 1;
i2 = 2;
printf("i1: %d\n", i1);
#ifdef USETHREADS
pthread_t r1_thread, r2_thread;
pthread_create(&r1_thread, NULL, r1, &i1);
pthread_create(&r2_thread, NULL, r2, &i1);
pthread_join(r1_thread, NULL);
pthread_join(r2_thread, NULL);
#else
r1(&i1);
r2(&i1);
#endif
printf("i1: %d\n", i1);
return 0;
}
所以有两个线程,一个在增加i1,一个在减少(我知道pthreads中有“mutex”,但目前还没有使用),所以为了避免竞争条件,我创建了mylock(我猜它伪造了mutex),让我吃惊的是,进程在等待mylock更改值时被困在一个未定义的循环中,除非我在等待循环中调用
printf
Primtf调用它的出口正如预期2秒,这是Linux的神秘? 最佳答案
您的程序通过访问mylock
而不进行同步来调用未定义的行为。在访问之前,您需要调用pthread_mutex_lock
(在您选择保护mylock
状态的互斥体上),完成后调用pthread_mutex_unlock
。当然,那么mylock
可能是无用的;您可以直接使用pthread_mutex_lock
进行锁定。
也就是说,如果你想学习线程,你的方法是完全错误的。一开始你不会试图滚动你自己的同步原语。在很大程度上,你不应该这样做,即使你是一个专家,除非你有非常不寻常的需要,即使这样,这可能是一个坏主意。给自己一个好的线程教程,教你如何正确使用同步原语,然后使用它们。