gpt4 book ai didi

线程可以在不锁定的情况下写入同一结构数组的不同元素吗?

转载 作者:太空狗 更新时间:2023-10-29 16:38:35 25 4
gpt4 key购买 nike

我正在尝试在 GCC C 应用程序中使用线程(这是第一次!),该应用程序在非线程模式下运行良好。当我运行它时,一些线程给出的结果全为零而不是所需的答案(我知道这是为了检查目的),但是每次运行它时给出零的线程都不相同。给出非零答案的那些是正确的,因此代码看起来运行正常。我想知道是否有人可以指出我可能有一些非线程安全的地方。

我自己的想法是,这可能是由于我收集结果的方式或内存分配所致——我使用 malloc 和 free,但在 StackOverflow 的其他地方,我看到如果与 -lpthread 链接(我正在做的),GCC malloc 被认为是线程安全的).没有使用全局/静态变量 - 一切都作为函数参数传递。

为了将结果传回 main,我的线程例程使用了一个结构数组。每个线程写入此数组的不同元素,因此它们不会尝试写入同一内​​存。也许我需要在写入结果时使用某种形式的锁定,即使它们不会转到结构数组的相同元素?

我在这里遵循线程代码的配方: https://computing.llnl.gov/tutorials/pthreads/#Abstract

我附上(简化的)代码摘录,以防这提供任何线索(我可能遗漏/修改了不正确的东西,但我不要求任何人发现错误,只是一般方法)。

typedef struct p_struct { /* used for communicating results back to main */
int given[CELLS];
int type;
int status;
/*... etc */
} puzstru;

typedef struct params_struct { /* used for calling generate function using threads */
long seed;
char *text;
puzzle *puzzp;
bool unique;
int required;
} paramstru;
/* ========================================================================================== */
void *myfunc(void *spv) /* calling routine for use by threads */
{
paramstru *sp=(paramstru *)spv;
generate(sp->seed, sp->text, sp->puzzp, sp->unique, sp->required);
pthread_exit((void*) spv);
}
/* ========================================================================================== */
int generate(long seed, char *text, puzstru *puzzp, bool unique, int required)
{
/* working code , also uses malloc and free,
puts results in the element of a structure array pointed to by "puzzp",
which is different for each thread
(see calling routine below : params->puzzp=puz+thr; )
extract as follows: */
puzzp->given[ix]=calcgiven[ix];
puzzp->type=1;
puzzp->status=1;
/* ... etc */
}
/* ========================================================================================== */


int main(int argc, char* argv[])
{
pthread_t thread[NUM_THREADS];
pthread_attr_t threadattr;
int thr,threadretcode;
void *threadstatus;
paramstru params[1];

/* ....... ETC */

/* set up params structure for function calling parameters */
params->text=mytext;
params->unique=TRUE;
params->required=1;

/* Initialize and set thread detached attribute */
pthread_attr_init(&threadattr);
pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_JOINABLE);

for(thr=0; thr<NUM_THREADS; thr++)
{
printf("Main: creating thread %d\n", thr);
params->seed=ran_arr_next(startingseeds);
params->puzzp=puz+thr;
threadretcode = pthread_create(&thread[thr], &threadattr, myfunc, (void *)params);
if (threadretcode)
{
printf("ERROR; return code from pthread_create() is %d\n", threadretcode);
exit(-1);
}
}

/* Free thread attribute and wait for the other threads */
pthread_attr_destroy(&threadattr);
for(thr=0; thr<NUM_THREADS; thr++)
{
threadretcode = pthread_join(thread[thr], &threadstatus);
if (threadretcode)
{
printf("ERROR; return code from pthread_join() is %d\n", threadretcode);
exit(-1);
}
printf("Main: completed join with thread %d having a status of %ld\n",thr,(long)threadstatus);
}

/* non-threaded code, print results etc ............. */

free(startingseeds);
free(puz);
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL);
}

为了阅读本文的其他人的利益 - 所有答案都是正确的,标题中问题的答案是肯定的,线程可以安全地写入同一结构数组的不同元素,我的问题出在调用例程中- 以下是修改后的代码片段(现在可以正常工作):

    paramstru params[NUM_THREADS];

for(thr=0; thr<NUM_THREADS; thr++)
{
printf("Main: creating thread %d\n", thr);
/* set up params structure for function calling parameters */
params[thr].text=mytext;
params[thr].unique=TRUE;
params[thr].required=1;
params[thr].seed=ran_arr_next(startingseeds);
params[thr].puzzp=puz+thr;
threadretcode = pthread_create(&thread[thr], &threadattr, myfunc, (void *)&params[thr]);
if (threadretcode)
{
printf("ERROR; return code from pthread_create() is %d\n", threadretcode);
exit(-1);
}
}

最佳答案

为了回答您的问题,从不同线程写入同一数组的不同元素而无需锁定是完全没问题的。永远只会有一个 data race如果两个线程在没有同步(例如,锁定)的情况下写入相同的字节

正如其他答案所指出的,您编写的代码中断的原因是因为您将指向同一 params 对象的指针传递给每个线程,然后修改该对象。您可能想为每个线程创建一个新的 param

关于线程可以在不锁定的情况下写入同一结构数组的不同元素吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5316379/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com