【问题标题】:Struct passed to thread (unix) has wrong values传递给线程(unix)的结构具有错误的值
【发布时间】:2014-03-16 13:54:35
【问题描述】:

我正在用 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-1threads,并将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)应该接收argk=0j=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

我尝试在每个pthread_create() 之后usleep 主线程。结果是,如果我让它休眠至少 60 微秒,问题就解决了……但是我怎样才能避免 usleep 而没有错误的值呢?

【问题讨论】:

  • 您的代码在 Mac OS 上运行良好。我刚刚在顶部添加了pthread_t tid[n-1],在底部的循环中添加了pthread_join(tid[i], NULL),它可以满足您的期望。也许您在其他地方有错误?我建议启用所有编译器警告并在 valgrind 下运行程序。
  • 鉴于让主线程休眠足够长的时间“解决”了问题,这表明启动线程后主线程中的一些代码正在破坏线程的数据结构正在尝试使用。我同意amdn 的观点,即问题不在您显示的代码中。请研究有关如何创建 MCTRE How to create a Minimal, Complete, Tested and Readable example 或 SSCCE (Short, Self-Contained, Correct Example) 的指南。

标签: c multithreading unix struct pthreads


【解决方案1】:

问题可能出在您在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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 2018-04-17
    • 1970-01-01
    • 2023-03-05
    • 2014-05-05
    • 1970-01-01
    • 2023-03-18
    • 2010-09-22
    相关资源
    最近更新 更多