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
,但是错误代码是由函数返回的。您是对的。谢谢你的更正。编辑原始帖子以反映这一点。为什么不在您的
添加