pthread 中的内存访问
Memory access in 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]);
}
}
我感到困惑的是所有线程都将 return NULL(用 gdb 检查),但是 err_array[1] 和 err_array[5] 将不是无效的。而不是有效的 err_type,它们将包含垃圾。如err_array[1]会包含一串unit_test文件路径,而err_array[5]会包含一堆访问越界地址。
我发现的一种解决方法是使用全局 err_array,并将每个元素的索引传递给线程。以及将数组的所有元素初始化为 NULL。
我的问题是为什么以上2种方法有效,而不是原来的代码?
err
变量是 thread_func
的本地变量。它在 thread_func
returns 时超出范围。您需要向线程传递一个指向您希望它修改的内容的指针,而不是您希望它修改的内容的当前值。
所以:
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]);
我正在编写涉及 运行 个多线程的单元测试,我 运行 遇到了一个我似乎无法理解的内存访问问题。
这里是原始(伪)代码:
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]);
}
}
我感到困惑的是所有线程都将 return NULL(用 gdb 检查),但是 err_array[1] 和 err_array[5] 将不是无效的。而不是有效的 err_type,它们将包含垃圾。如err_array[1]会包含一串unit_test文件路径,而err_array[5]会包含一堆访问越界地址。
我发现的一种解决方法是使用全局 err_array,并将每个元素的索引传递给线程。以及将数组的所有元素初始化为 NULL。
我的问题是为什么以上2种方法有效,而不是原来的代码?
err
变量是 thread_func
的本地变量。它在 thread_func
returns 时超出范围。您需要向线程传递一个指向您希望它修改的内容的指针,而不是您希望它修改的内容的当前值。
所以:
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]);