pthreads中的内存访问

时间:2015-12-07 19:29:26

标签: c multithreading memory concurrency pthreads

我正在编写一个涉及运行多个线程的单元测试,但我遇到了一个我似乎无法理解的内存访问问题。

这是原始(伪)代码:

void thread_func(void * err) {
    /*foo will return an allocated error_type if error occurs else NULL*/
    err = (void *) foo(...)
    pthread_exit(NULL);
}

void unit_test() {
    int i = 0;
    err_type *err_array[10];
    pthread_t threads[10];
    for (i = 0; i < 10; i++) {
         pthread_create(&(threads[i]), NULL, thread_func, (void *) err_array[i]);
    }
    for(i = 0; i < 10; i++) {
         pthread_join(threads[i], NULL);
         ASSERT_NULL(err_array[i]);
     }
}

我感到困惑的是,所有线程都将返回NULL(使用gdb检查),但是err_array [1]和err_array [5]将是NOT NULL。而不是有效的err_type,它们将包含垃圾。在err_array [1]的情况下,将包含unit_test文件路径的字符串,并且err_array [5]将包含一堆超出边界地址的访问。

我找到的解决方法是使用全局err_array,并将每个元素的索引传递给线程。以及将数组的所有元素初始化为NULL。

我的问题是为什么上述两种方法都有效,而不是原始代码?

1 个答案:

答案 0 :(得分:1)

err变量是thread_func的本地变量。当thread_func返回时,它超出范围。你需要向线程传递一个指向你想要它修改的东西的指针,而不是你希望它修改的东西的当前值。

所以:

void thread_func(void ** err) {
    /*foo will return an allocated error_type if error occurs else NULL*/
    *err = (void *) foo(...)
    pthread_exit(NULL);
}

     pthread_create(&(threads[i]), NULL, thread_func, (void **) &err_array[i]);