gpt4 book ai didi

c - 多线程程序中的意外输出

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:16:04 26 4
gpt4 key购买 nike

下面是一个使用pthreads的程序。

#include <pthread.h> // posix threads 
#include <stdio.h>
#include <stdlib.h>

/* to compile use -lpthread */

void * sample_thread(void *);

#define MAX 10

int main()
{
pthread_t tid;
pthread_attr_t attr;
int k;

pthread_attr_init(&attr); // set default attributes
pthread_create(&tid, &attr, sample_thread, NULL); // create new thread
// sample_thread will run as the new thread

for(k=0; k<MAX; k++) {
printf("Hi I'am %s %d \n",__func__,k);
}


//this would kill all the threads,
}

void * sample_thread(void * p)
{
int k;
for(k=0; k<MAX; k++) {
printf("Hi I'am %s %d \n",__func__,k);
}

}

每次运行程序时,我都希望从主线程和子线程获得不同数量的执行次数(因为主线程可能在子线程之前退出)。我有时会得到这个预期的输出。但是我得到了如下输出,我无法理解为什么。

Hi I'am main 0 
Hi I'am main 1
Hi I'am main 2
Hi I'am main 3
Hi I'am main 4
Hi I'am main 5
Hi I'am main 6
Hi I'am main 7
Hi I'am main 8
Hi I'am main 9
Hi I'am sample_thread 0
Hi I'am sample_thread 0
Hi I'am sample_thread 1
Hi I'am sample_thread 2
Hi I'am sample_thread 3
Hi I'am sample_thread 4
Hi I'am sample_thread 4
Hi I'am sample_thread 5

为什么示例线程 0 和 4 打印了两次?

最佳答案

正如 @R.. 在评论中强调的那样,这似乎是 a bug在 glibc 的实现中(假设您使用的是 Linux——我可以在使用 GCC 4.9.1 编译的 Linux 2.17 上重现它),因为 exit() 不能确保,同时刷新和关闭流,当多个线程使用 stdout 时,当它被一个线程调用时没有竞争。

flockfile 手册中的以下内容清楚地表明观察到的行为是不正确的:

The stdio functions are thread-safe. This is achieved by assigning to each FILE object a lockcount and (if the lockcount is nonzero) an owning thread. For each library call, these functions wait until the FILE object is no longer locked by a different thread, then lock it, do the requested I/O, and unlock the object again.

鉴于此,对于我们在此观察到的这种特殊情况,可以将以下选项视为解决方法(因为没有对错误报告的响应)。


两个线程“共享”stdout 流,我认为,由于主线程过早退出,打印了“额外”输出。

printf 缓冲(在 sample_thread() 中)输出并在它清除缓冲区之前(由于 printfs 中的 \n),主线程退出。因此在进程退出时强制刷新 stdout 缓冲区。

修复,

1) 你可以在创建线程之前调用 main() 中的 setbuf():

setbuf(stdout, NULL);

根本缓冲stdout

或者
2) 在两个线程中调用 pthread_exit(),以便在任一线程死亡时进程继续。

或者
3) 在主线程中调用pthread_join(),让主线程等待sample_thread线程完成。

其中任何一个都可以避免这个问题。

关于c - 多线程程序中的意外输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51649563/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com