C 当使用互斥时,“;printf";输出两次(或更多?我不确定)?
我在学习线程同步。我的测试代码如下:C 当使用互斥时,“;printf";输出两次(或更多?我不确定)?,c,linux,multithreading,mutex,C,Linux,Multithreading,Mutex,我在学习线程同步。我的测试代码如下: #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_mu
#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;
}
#包括
#包括
pthread_cond_t cond=pthread_cond_初始值设定项;
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
整数计数=0;
void*添加(void*参数)
{
而(1)
{
pthread_mutex_lock(&mutex);
fprintf(标准输出,“线程:%ld,计数:%d\n”,pthread\u self(),计数);
计数++;
pthread_mutex_unlock(&mutex);
}
返回0;
}
作废*打印(作废*参数)
{
而(1)
{
pthread_mutex_lock(&mutex);
如果(计数>100)
{
printf(“计数大于100,计数:%d\n”,计数);
pthread_mutex_unlock(&mutex);
打破
}
pthread_mutex_unlock(&mutex);
}
返回0;
}
内部主(空)
{
pthread_t thread1、thread2、thread3;
pthread_mutex_init(&mutex,NULL);
pthread_create(&thread1,NULL,add,NULL);
pthread_create(&thread2,NULL,add,NULL);
pthread_创建(&thread3,NULL,print,NULL);
pthread_join(thread3,NULL);
pthread_mutex_destroy(&mutex);
返回0;
}
我以为“计数”的每一个产量都会连续增加一个。但事实却大不相同,就像:
//程序输出开始:线程:139663694870272,计数: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,
计数:172计数大于100,计数:173线程:139663686477568,
计数:173线程:139663686477568,计数:174线程:139663686477568,
计数:175线程:139663686477568,计数:176线程:139663686477568,
计数:177线程:139663686477568,计数:178线程:139663686477568,
计数:179线程:139663686477568,计数:180线程:139663686477568,
计数:181线程:139663686477568,计数:182线程:139663686477568,
计数:183线程:139663686477568,计数:184线程:139663686477568,
计数:185线程:139663686477568,计数:186线程:139663686477568,
计数:187线程:139663686477568,计数:188线程:139663686477568,
计数:189线程:139663686477568,计数:190线程:139663686477568,
计数:191线程:139663686477568,计数:192线程:139663686477568,
计数:193线程:139663686477568,计数:194线程:139663686477568,
计数:195线程:139663686477568,计数:196线程:139663686477568,
计数:197线程:139663686477568,计数:198线程:139663686477568,
计数:199线程:139663686477568,计数:200线程: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在这种情况下做什么?为什么它会输出两次。一旦互斥锁被破坏,所有赌注都将被取消。在确定没有线程可以使用互斥锁之前,不应销毁互斥锁。David给出了正确答案。。。在所有线程退出之前,不要销毁互斥锁。我只是想在这方面做一点扩展,因为您似乎只是在学习pthreads 尝试更改
添加,如下所示:
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\u mutex\u lock
的返回值始终。您可以检查返回值以了解其失败的原因,但通常,如果锁定失败,您不希望访问受锁定保护的资源
add
线程知道如何/何时关闭自己也是一种很好的做法。我在这里展示的只是一种方法
另外,仅供参考,main中的pthread\u mutex\u destroy()
远远不能保证成功。当互斥锁被锁定或引用时(例如,通过条件变量),不能销毁互斥锁。因此,如果尝试销毁时add
具有锁,pthread\u mutex\u destroy()
应返回一个错误。在100次迭代后销毁互斥锁。我很惊讶没有其他东西会完全崩溃。你用什么命令行编译这段代码?您是否指定了平台对POSIX pthreads支持的要求?(可能是-pthread
)@David Schwartz我只使用“gcc pthread_mutex.c-lpthread”和“a.out”是我的输出文件。@seven你应该使用-pthread
,而不是-lpthread
。但这可能不会对你的平台产生任何影响。你确定你的输出来自你发布的同一个程序吗?计数后的逗号出现在输出中,但代码中没有任何内容产生这种情况。重要编辑:最初将count>0
而不是count>100
作为设置quit=1
的条件。我现在已经解决了这个问题。“您可以检查errno
以查看…”不,最近的PThread实现没有设置errno
,但是错误代码是由函数返回的。您是对的。谢谢你的更正。编辑原始帖子以反映这一点。为什么不在您的添加: