gpt4 book ai didi

c - Pthreads 而不是共享变量

转载 作者:太空宇宙 更新时间:2023-11-04 06:51:22 25 4
gpt4 key购买 nike

在学习本教程时: https://www.pluralsight.com/courses/linux-network-programming我发现了非常有趣的行为,请检查以下代码:

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

void *func(void *arg)
{
pthread_exit((void *)99);
}

int main()
{
pthread_t handle;
int exitcode;
int i = 0;
int y = 5;
while (1) {
y++;
// i++;
printf("primary thread: y == %d\n", y);
pthread_create(&handle, NULL, func, "hi!");
pthread_join(handle, (void **)&exitcode);
sleep(1);
}
}

//gcc -o t failtesting.c -O0 -l pthread ; ./t
//primary thread: y == 6
//primary thread: y == 1
//primary thread: y == 1
//^C

以某种方式加入子线程会将变量 y 重置为 0,为什么会这样?

最奇怪的部分是:如果你取消注释 i++,一切都会恢复正常:

gcc -o t failtesting.c -O0  -l pthread  ; ./t 
primary thread: y == 5
primary thread: y == 6
primary thread: y == 7
primary thread: y == 8

最佳答案

这...

    int exitcode;

[...]

        pthread_join(handle, (void **)&exitcode);

... 产生未定义的行为,因为 &exitcode 的引用是一个 int,但是 pthread_join 会导致向其写入一个值就好像它是一个 void *

这本身就足以使行为未定义,而不管任何其他考虑因素。但是,在考虑 为什么 C 可能将这种情况声明为 UB 时,请务必考虑 void * 的大小大于一个 int,那么当程序试图将数据写入一个对它来说太小的空间时应该发生什么?

The weirdest part is: if you uncomment i++, everything goes back to normal

诸如此类的异常情况表明您的程序存在 UB。 C 标准明确否认对此有任何解释——这是“未定义行为”的部分含义。

无论如何,看起来你想要这个,而不是:

    void *exit_ptr;
pthread_join(handle, &exit_ptr);
exitcode = (int) exit_ptr;

请准备好让编译器发出关于指针转换为 int 的合理警告,尽管您应该能够通过转换为 intptr_t 来消除它。

关于c - Pthreads 而不是共享变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50671022/

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