我用pthreads编写了一个简单的程序,它通过一个结构将多个参数传递给被调用的函数。考虑这两个程序:
程序1:
#include <pthread.h>
#include <stdio.h>
#include <malloc.h>
struct args{
long long val1;
int val2;
};
void *hello(void* threadid){
struct args *tid;
tid=(struct args*)threadid;
printf("thread %lld\n",tid->val1);
pthread_exit(NULL);
}
int main(){
pthread_t threads[20];
int i;
for(i=0;i<20;i++){
// ***** specific memory given to the struct *****
struct args* a1=(struct args*)malloc(sizeof(struct args));
a1->val1=i;
a1->val2=i+1;
int ret=pthread_create(&threads[i],NULL,hello,(void*)a1);
if(ret){
printf("error code %d for %d\n",ret,i);
}
}
pthread_exit(NULL);
}
它按预期打印输出,
0..19
另一方面,考虑
程序p2
#include <pthread.h>
#include <stdio.h>
struct args{
long long val1;
int val2;
};
void *hello(void* threadid){
struct args *tid;
tid=(struct args*)threadid;
printf("thread %lld\n",tid->val1);
pthread_exit(NULL);
}
int main(){
pthread_t threads[20];
int i;
for(i=0;i<20;i++){
// ***** struct made like normal declarations *****
struct args a1;
a1.val1=i;
a1.val2=i+1;
int ret=pthread_create(&threads[i],NULL,hello,(void*)&a1);
if(ret){
printf("error code %d for %d\n",ret,i);
}
}
pthread_exit(NULL);
}
这个程序有重复和不完整的条目,如
thread 3
thread 5
thread 3
thread 4
thread 3
thread 6
thread 7
thread 8
thread 9
thread 10
thread 11
thread 12
thread 13
thread 15
thread 15
thread 16
thread 17
thread 18
thread 19
thread 19
为什么结构的实例化会直接导致这种重叠?难道C不应该为循环中的每一次提供一个新的内存块吗?
最佳答案
在第二个示例中,a1
是用for
循环中的自动存储持续时间声明的。这意味着在每次迭代结束时,该存储位置可能会被重新用于下一次迭代。因此:
int ret=pthread_create(&threads[i],NULL,hello,(void*)&a1);
…您可能正在将地址(
&a1
)传递到将在后续迭代中修改的内存位置。另一方面,将在每次迭代时分配一个指向不同内存位置的指针。由于无法保证线程是否在下一次迭代开始之前或之后执行,因此每次运行上述代码时,您可能会得到不同的结果。
此外,如果使用
malloc
而不将指针存储在任何地方或在线程中释放它们,则会导致内存泄漏。在所有线程完成之前,结构也可能超出范围,结果是它们访问了一个悬挂的指针。最后,由于您没有加入任何线程,因此无法确定程序退出之前将有多少实际执行。欢迎来到多线程的奇妙世界。
关于c - pthreads:由于malloc和直接声明而引起的差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14836679/