gpt4 book ai didi

c - 多线程编程 C.互斥量不起作用

转载 作者:行者123 更新时间:2023-12-01 12:51:30 25 4
gpt4 key购买 nike

我有一个用 pthreads 编写的多线程 c 程序。我想知道我所做的是否正确。目前该程序似乎在没有优化的情况下运行。但是当我使用优化时,它失败了。我想找出原因。

我想知道我使用的基本多线程同步是否正确。这是一个简短的版本,仅包含相关部分。请让我知道这是否是多线程的正确方法。

工作原理:每个 worker 都有许多工作要做。首先启动工作线程。然后他们等待直到主线程分配给他们一个工作。他们完成工作,关闭主线程并再次返回等待。

主线程将工作分配给 N 个 worker 并通知他们开始。然后等待它们完成并恢复正常工作。

每个工作线程都有一个名为 workerCtx 的上下文变量。这存储了工作人员所需的所有相关信息以及互斥锁和 cond 变量。

主线程也有一个 mutex 和一个 cond 变量。

父级也有称为 threadCompletionCount 的变量。在分配工作之前,该变量最初为 0。一旦每个工作线程完成,它将在互斥锁的保护下将该变量递增 1,并向父线程发出信号。当这个变量等于worker的数量时,父线程就会知道所有的worker已经完成。

这是 workerCtx 的简短版本

typedef enum {INITIALIZE = 0 , WAIT = 1, WORK1 = 2, WORK2 =3, DIE = 4} worktype_t;

typedef struct workerCtx_t
{
int id;

pthread_mutex_t mutex;
pthread_cond_t cond;

pthread_mutex_t * parentMutex;
pthread_cond_t * parentCond;
int * parentThreadCompletionCount;

worktype_t workType;

//Other application specific variables follow.
}workerCtx_t;

这里的mutex和cond是指本线程特有的局部mutex和cond变量。 parentMutex 和 parentCond 是引用父变量的变量。所有线程都指向同一个 parentMutex 和 parentCond。

这是主线程的工作方式:

void waitForWorkerCompletion()
{
int status;

status = pthread_mutex_lock(&mutex);
while (threadCompletionCount < NUM_WORKERS)
{
status = pthread_cond_wait(&cond, &mutex);
}
status = pthread_mutex_unlock(&mutex);

status = pthread_mutex_lock(&mutex);
threadCompletionCount = 0;
status = pthread_mutex_unlock(&mutex);
}

void assignWorkToWorker(worktype_t workType)
{
for(int i=0; i<NUM_WORKERS; i++)
{
pthread_mutex_lock(&(workerCtxs[i]->mutex) );
workerCtxs[i]->workType = workType;
pthread_cond_signal(&(workerCtxs[i]->cond) );
pthread_mutex_unlock(&(workerCtxs[i]->mutex));
}
waitForWorkerCompletion();
}

void setup
{
for(int i=0; i<NUM_WORKERS; i++)
{
workerCtxs[i]->id = i;
workerCtxs[i]->workType = WAIT;

assert( pthread_mutex_init(&(workerCtxs[i]->mutex), NULL) == 0) ;
assert( pthread_cond_init(&(workerCtxs[i]->cond), NULL) == 0);

workerCtxs[i]->parentMutex = &mutex;
workerCtxs[i]->parentCond = &cond;
workerCtxs[i]->parentThreadCompletionCount = &threadCompletionCount;

pthread_create (&(workers[i]), NULL, workerMain, (workerCtxs[i]) );

}
}

int main()
{
setup()

For each work (workType_t workType) that comes up
assignWorkToWorker(workType);
}

这是每个 worker 的工作:

void signalCompletion(workerCtx_t * ctx)
{
pthread_mutex_lock(&ctx->mutex);
ctx->workType = WAIT;
pthread_mutex_unlock(&ctx->mutex);

int rc = pthread_mutex_lock(ctx->parentMutex);
*(ctx->parentThreadCompletionCount) = *(ctx->parentThreadCompletionCount) + 1;
pthread_cond_signal(ctx->parentCond);
rc = pthread_mutex_unlock(ctx->parentMutex);
}

void * workerMain(void * arg)
{
workerCtx_t * ctx = (workerCtx_t *) arg;

while(1)
{
pthread_mutex_lock(&ctx->mutex);
while(ctx->workType == WAIT);
{
int status = pthread_cond_wait(&ctx->cond, &ctx->mutex);
}
pthread_mutex_unlock(&ctx->mutex);

if(ctx->workType == INITIALIZE)
{
init(ctx);
signalCompletion(ctx);
}
else if(ctx->workType == WORK1)
{
doWork1(ctx);
signalCompletion(ctx);
}
else if(ctx->workType == WORK2)
{
doWork2(ctx);
signalCompletion(ctx);
}
else if(ctx->workType == DIE)
{
signalCompletion(ctx);
break;
}
}

return NULL;
}

我希望我已经使它足够容易理解,并从发布的代码中删除了所有面向应用程序的细节。这段代码只处理多线程部分。现在程序挂了。当我使用 gdb 时,它告诉我它正在 waitForWorkerCompletion() 方法中等待。

这个多线程模型正确吗??

最佳答案

搞什么鬼,我会把它作为一个答案。

下面这行看起来很可疑:

while(ctx->workType == WAIT);

我不认为你想要那里的分号。有了它,您会遇到各种奇怪的竞争条件……这可以解释为什么未优化和优化构建之间的行为不同。

否则,我认为这段代码没有任何问题。使用工作池的方式有点奇怪,但在我看来应该可行。

关于c - 多线程编程 C.互斥量不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12187641/

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