使用条件创建多线程和递增计数器
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
一次。为此,您需要
以将分配的标识符传递给每个线程的方式实现“为每个任务分配一个 id 标识符”的规范。为不同的线程提供不同的数据通常涉及使用 pthread_create()
的第四个参数,线程函数接收它作为它的(唯一)参数。
将条件变量与互斥锁一起使用,使线程能够在等待轮到它们时暂停操作。您可以在 SO 上找到许多关于如何正确执行此操作的答案。
当轮到线程递增计数器时,它只执行一次递增,而不是多次递增,并且它不会修改自己分配的 ID。
还有很多细节需要你去解决。我将这些保留为它们本来的练习。
我正在尝试用 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
最初取值 0int 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
一次。为此,您需要
以将分配的标识符传递给每个线程的方式实现“为每个任务分配一个 id 标识符”的规范。为不同的线程提供不同的数据通常涉及使用
pthread_create()
的第四个参数,线程函数接收它作为它的(唯一)参数。将条件变量与互斥锁一起使用,使线程能够在等待轮到它们时暂停操作。您可以在 SO 上找到许多关于如何正确执行此操作的答案。
当轮到线程递增计数器时,它只执行一次递增,而不是多次递增,并且它不会修改自己分配的 ID。
还有很多细节需要你去解决。我将这些保留为它们本来的练习。