我正在学习线程同步。我的测试代码如下:
#include <pthread.h>
#include <stdio.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int count = 0;
void* add(void * params)
{
while(1)
{
pthread_mutex_lock(&mutex);
fprintf(stdout, "thread:%ld, count:%d\n",pthread_self(), count);
count++;
pthread_mutex_unlock(&mutex);
}
return 0;
}
void* print(void * params)
{
while(1)
{
pthread_mutex_lock(&mutex);
if (count > 100)
{
printf("count greater than 100,count: %d\n", count);
pthread_mutex_unlock(&mutex);
break;
}
pthread_mutex_unlock(&mutex);
}
return 0;
}
int main(void)
{
pthread_t thread1, thread2, thread3;
pthread_mutex_init(&mutex, NULL);
pthread_create(&thread1, NULL, add, NULL);
pthread_create(&thread2, NULL, add, NULL);
pthread_create(&thread3, NULL, print, NULL);
pthread_join(thread3, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
我认为“计数”的每个输出都会连续增加一个。然而,事实却完全不同。就像:
//程序输出开始:thread:139663694870272,count:0 线程:139663694870272,计数:1个主题:139663694870272,计数:2 线程:139663694870272,计数:3线程:139663694870272,计数:4 线程:139663694870272,计数:5个主题:139663686477568,计数:6 线程:139663686477568,计数:7个主题:139663686477568,计数:8 线程:139663686477568,计数:9线程:139663686477568,计数:10 线程:139663686477568,计数:11个主题:139663686477568,计数:12 线程:139663686477568,计数:13线程:139663686477568,计数:14 线程:139663686477568,计数:15个主题:139663686477568,计数:16 线程:139663686477568,计数:17个主题:139663686477568,计数:18 线程:139663686477568,计数:19线程:139663686477568,计数:20 线程:139663686477568,计数:21线程:139663686477568,计数:22 (...............有些行被忽略)主题:139663686477568, count:172 count大于100,count:173 thread:139663686477568, 计数:173线程:139663686477568,计数:174线程:139663686477568, 计数:175线程:139663686477568,计数:176线程:139663686477568, count:177 thread:139663686477568,count:178 thread:139663686477568, count:179 thread:139663686477568,count:180 thread:139663686477568, count:181 thread:139663686477568,count:182 thread:139663686477568, 计数:183线程:139663686477568,计数:184线程:139663686477568, 计数:185线程:139663686477568,计数:186线程:139663686477568, 计数:187线程:139663686477568,计数:188线程:139663686477568, count:189 thread:139663686477568,count:190 thread:139663686477568, count:191 thread:139663686477568,count:192 thread:139663686477568, 计数:193线程:139663686477568,计数:194线程:139663686477568, 计数:195线程:139663686477568,计数:196线程:139663686477568, count:197 thread:139663686477568,count:198 thread:139663686477568, count:199 thread:139663686477568,count:200 thread:139663686477568, 计数:201线程:139663686477568,计数:202线程:139663686477568, 计数:203线程:139663686477568,计数:204线程:139663686477568, 数:205 主题:139663686477568,计数:206主题:139663686477568,计数:206 主题:139663686477568,计数:207主题:139663686477568, 计数:208线程:139663686477568,计数:209 主题:139663686477568,计数:210线程:139663686477568,计数:210 主题:139663686477568,计数:211
我不知道在这种情况下“printf”会做什么?为什么输出两次。
答案 0 :(得分:3)
一旦互斥锁被破坏,所有赌注都将被取消。在确定没有线程可以使用它之前,不应销毁互斥锁。
答案 1 :(得分:3)
David有正确的答案......在所有线程退出之前不要破坏互斥锁。我只是想稍微扩展一下,因为你似乎只是在学习pthreads。
尝试将add
更改为以下内容:
void* add(void * params)
{
int quit =0;
while(!quit)
{
if( 0 == pthread_mutex_lock(&mutex) )
{
fprintf(stdout, "thread:%ld, count:%d\n",pthread_self(), count);
count++;
if( count > 100 ) quit = 1;
pthread_mutex_unlock(&mutex);
}
else
{
fprintf(stderr, "Failed to lock mutex. Exiting.\n");
quit=1;
}
}
return 0;
}
有两大变化:
检查pthread_mutex_lock
的返回值。 始终即可。您可以检查返回值以查看失败的原因,但通常如果锁定失败,您不希望访问受锁定保护的资源。
add
线程知道如何/何时关闭自己也是一种好习惯。我在这里展示的只是一种方法。
另外,仅供参考,主要的pthread_mutex_destroy()
远非保证无论如何都能成功。在锁定或引用互斥锁时(例如通过条件变量),不能销毁互斥锁。因此,如果add
在尝试销毁时遇到锁定,pthread_mutex_destroy()
应该返回错误。