我在C(基于Unix)中基于并发编写了一段代码,但似乎在最基础上存在一些问题。
我有一个像这样的全局结构:
struct i_arg {
int k;
int j;
};
在运行时,我采用最大数量N
并分配一个struct i_arg
数组,其大小为N-1
struct i_arg *t_arg;
...
t_arg = (struct i_arg *) malloc((n-1) * sizeof(struct i_arg));
for(i = 0; i < n-1; i++) {
t_arg[i].k = i;
t_arg[i].j = i+1;
}
...
鉴于N
,我还创建了N-1
个帖子,并将t_arg[i]
的指针传递给每个
for(i = 0; i < n-1; i++) {
retcode = pthread_create(&tid[i], NULL, swap, (void *) &t_arg[i]);
if (retcode != 0)
fprintf(stderr, "Creation of thread %d failed.\n", i);
}
并且swap
函数立即执行转换为(struct i_arg)
:
void *swap(void *arg) {
struct i_arg *ind;
int i,j;
ind = (struct i_arg *) arg;
i = ind->k;
j = ind->j;
fprintf(stdout,"Thread %d working... with i= %d, i+1=%d\n", i, i, j);
...
pthread_exit(0);
}
现在问题是:
当N
为偶数时,创建的第一个线程(线程0)应该arg
和k=0
接收j=1
。实际上它接收j=1
但k从0变为随机数。
fprintf
将打印
Thread 4747264 working... with i= 4747264, i+1=1
如果N
为奇数,则第一个线程运行平稳,输出正确
Thread 0 working... with i= 0, i+1=1
我在每个usleep
之后尝试pthread_create()
主线程。结果是,如果我让它睡眠至少60微秒,问题就解决了......但是如果没有错误值我怎么能避免usleep
?
答案 0 :(得分:0)
问题可能在于您在swap
函数中剪切并显示为...
的代码,是否存储回i_arg结构的t_arg数组?
for(i = 0; i < n-1; i++) {
t_arg[i].k = i;
t_arg[i].j = i+1;
}
当i == n-2时,您将j初始化为n-1,这是您的数组大小之一。这就是你分配的方式:
t_arg = (struct i_arg *) malloc((n-1) * sizeof(struct i_arg));
这就是你初始化的方式
t_arg[i].j = i+1; /* bug is likely here when i==n-2, */
如果使用t_arg[i].j
作为数组的索引,当i == n-2且j == n-1时,它将是未定义的。
我的建议是分配N
条目并发送N-1个线程。对于N
条目,只有N-1个相邻的东西要交换(对于N> 0)。
t_arg = (struct i_arg *) malloc( n * sizeof(struct i_arg) );
for(i = 0; i < n; i++) {
t_arg[i].k = i;
t_arg[i].j = i+1;
}