使用条件创建多线程和递增计数器

Creating multi threads and increment counter with condition

我正在尝试用 C 编写一个名为 thr_incrementer 的函数,变量按 N 个任务递增(N 由常量定义)。每个任务都分配了一个 id 标识符(在 0 和 N-1 之间)并且它们只在

时增加一个计数器

id = counter % N

现在我有了这个,但是,id = (counter % NTHREADS) 根本不起作用。

#include<stdio.h>
#include<pthread.h>

#define NTHREADS 10

void *thr_incrementer(void *);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter =0;


void *thr_incrementer(void *arg){
    
    int id = 0;
    
    pthread_mutex_lock (&mutex);

    for(id = 0; id <NTHREADS ; id++){

        if (id == (counter % NTHREADS)){
            counter++;
        }
        else{
            return NULL;
        }
    }
    pthread_mutex_unlock(&mutex);

    printf("ID: %d\n",id);
    
}


int main(){
    
    pthread_t thread[NTHREADS];
    int i;

    for ( i = 0; i < NTHREADS; i++){
        pthread_create(&thread[i], NULL, thr_incrementer, NULL);
    }


    if(pthread_mutex_destroy(&mutex) != 0){
        printf("Error destorying mutex.\n");
        return -1;
    }

    printf("Thread: %ln\n",thread);
 
}

For now i have this but, id = (counter % NTHREADS) [sic] doesn't work at all.

当然,你代码中的test其实是id == (counter % NTHREADS)===不一样)。该测试工作正常,但在给定的代码中毫无意义。考虑:

  • counter 最初取值 0

    int counter =0;
    
  • 每个线程都有自己的 local 变量 id,初始值为 0,每个线程在运行时修改它。这与问题描述的“每个任务都分配了一个 id 标识符”不匹配,代码中似乎也没有任何其他匹配该规定的内容。

  • 每个线程基本上完成所有工作,包括对单个临界区内的全局 counter 变量的所有修改。因此,不会交错其他线程的操作。

  • 每个线程在循环中递增其 id 变量。如果碰巧 id == (counter % NTHREADS) 那么它也会递增 counter。在这种情况下,该条件也将在下一次迭代中得到满足,因为 id 和 counter` 都递增 1。

  • 此外,id在每个线程中从0开始,counter在整个程序中从0开始。因此,第一个线程将递增 counter 的次数与它递增 id 的次数一样多——总计 NTHREADS 次。 NTHREADS % NTHREADS 为 0,因此当每个后续线程获取互斥锁时,同样的事情再次发生。

因此,问题不在于 id == (counter % NTHREADS) 不起作用,而在于,给定您的代码,在评估时它始终为真。

我最好的猜测是,您希望每个线程在轮到自己时仅增加 counter 一次。为此,您需要

  1. 以将分配的标识符传递给每个线程的方式实现“为每个任务分配一个 id 标识符”的规范。为不同的线程提供不同的数据通常涉及使用 pthread_create() 的第四个参数,线程函数接收它作为它的(唯一)参数。

  2. 将条件变量与互斥锁一起使用,使线程能够在等待轮到它们时暂停操作。您可以在 SO 上找到许多关于如何正确执行此操作的答案。

  3. 当轮到线程递增计数器时,它只执行一次递增,而不是多次递增,并且它不会修改自己分配的 ID。

还有很多细节需要你去解决。我将这些保留为它们本来的练习。