Pthreads而不是共享变量

时间:2018-06-03 21:13:19

标签: c pthreads

遵循本教程: 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

1 个答案:

答案 0 :(得分:3)

这......

    int exitcode;
     

[...]

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

...产生未定义的行为,因为&exitcode的引用是int,但pthread_join会导致将值写入void * }。

对于未定义的行为而言,这是完全足够的,无论其他任何考虑因素如何。但是,在考虑为什么 C可能会将此类情况声明为UB时,请考虑void *的大小大于{{1}的大小是很常见的当程序试图将数据写入太小的空间时,应该发生什么呢?

  

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

这种异常表明您的计划正在展示UB。 C标准明确否认有任何解释 - 这是什么&#34;未定义的行为&#34;装置

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

int

准备让编译器发出一个关于指针到int转换的合理的警告,尽管你应该能够通过转换为 void *exit_ptr; pthread_join(handle, &exit_ptr); exitcode = (int) exit_ptr; 来沉默它。