gpt4 book ai didi

c - 无法理解以下程序中的 pthread_create() 行为?

转载 作者:IT王子 更新时间:2023-10-29 01:20:19 25 4
gpt4 key购买 nike

#include <stdio.h>
#include <pthread.h>

void *thread_func(void *arg)
{
printf("hello, world \n");
return 0;
}

int main(void)
{
pthread_t t1, t2;

pthread_create(&t1, NULL, thread_func, NULL);
pthread_create(&t2, NULL, thread_func, NULL);

printf("t1 = %d\n",t1);
printf("t2 = %d\n",t2);

return 0;
}

上面的程序创建了两个线程,每个线程打印“Hello World”。

因此,根据我的理解,“Hello world”最多应打印 2 次。

但是,多次执行同一程序(背对背)时,在某些情况下,“Hello world”的打印 2 次。所以我不清楚它是如何打印出意想不到的次数的?

以下是示例输出:

[rr@ar ~]$ ./a.out
t1 = 1290651392
t2 = 1282258688
hello, world
hello, world


[rr@ar ~]$ ./a.out
t1 = 1530119936
t2 = 1521727232
hello, world
hello, world
hello, world

如上所示,多次执行程序后,"hello, world"打印了3次。谁能告诉我它为什么打印了 3 次?

最佳答案

您遇到了线程安全问题。我在 Linux 16.04 中多次运行您的代码,它产生许多不同的输出,而带有 3 个 hello world 消息的输出很少见。更常见的是根本没有输出,这意味着 main 终止的速度比线程能够完成其输出的速度更快。有时会产生部分输出,例如:

t1=xxxx
t2=yyyy
he

这意味着 main 正在退出,而只有一个线程能够将一些字符压入 stdout 缓冲区。请记住,main 的正常返回等同于调用刷新 stdio 缓冲区的 exit

虽然我无法真正理解当您观察到 3 条消息时幕后发生了什么,但我怀疑存在一个运行竞赛,让 main 刷新当前正在被一个缓冲区刷新的缓冲区的线程。如果不仔细检查 printf 的源代码,就很难再多说了。一个可能的(粗略的)场景如下:

  1. thread1 填充缓冲区并进入刷新但在开始时被抢占
  2. main 退出,因此进入刷新并终止它,并在它的最后被抢占,从而生成 hello world
  3. 线程 1 完成刷新生成 hello world
  4. thread2 产生hello world
  5. main 获取 CPU 并终止进程。

printf 没有被定义为线程安全的,这意味着实现者可能会实现也可能不会(在大多数情况下可能不会)。因此,与使用某些共享资源的任何函数一样,您需要一些互斥锁来防止缓冲区并发等。

在您的情况下,这应该通过在 main 中加入线程来大致解决(3 个输出),这将防止 main 在线程终止之前退出/刷新。但请注意,这不会解决其他并发问题(两个线程访问同一个缓冲区...)。

关于c - 无法理解以下程序中的 pthread_create() 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44276732/

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