【发布时间】:2017-05-21 03:14:29
【问题描述】:
我在 C 中练习 pthread,尝试制定一个在线程之间尽可能平均分配工作负载的函数。每个线程返回一个整数,表示分配给它们的工作量。
#include <stdio.h>
#include <pthread.h>
#define THREADS 3
#define ITEMS 10
pthread_mutex_t locker = PTHREAD_MUTEX_INITIALIZER;
void* worker(void* arg){
int id = *(int*)arg;
int chunk = ITEMS/THREADS;
int start = chunk * id;
int end = id == THREADS - 1 ? ITEMS : start + chunk;
for(int i = start; i < end; i ++){
//do some work;
}
pthread_mutex_lock(&locker);
//do some work
pthread_mutex_unlock(&locker);
return end - start; //here return type should be (void *), I casted it to (int).
}
int main(void){
pthread_t ids[THREADS];
int args[THREADS];
for(int i = 0; i < THREADS; i ++){
args[i] = i;
pthread_create(ids + i,NULL,worker,&args[i]);
}
int total = 0;
int temp;
for(int i = 0; i < THREADS; i ++){
pthread_join(ids[i],&temp); //param here should be (void**), I cast it to (int*)
total = total + temp;
printf("Thread %d process %d items\n",i,temp);
}
printf("Get total items:%d\n",total);
}
我想对每个线程的返回值求和,以检查是否所有项目都已处理。因为我比较懒,也只是小练习,所以直接把每个线程的返回值从(void *)投到(int)。然后我得到了一些让我很困惑的输出。事实证明我可以成功地从变量“temp”中读取值,但是当我尝试这样做时
total = total + temp;
total 的值没有改变...
我通过将“temp”的类型从int 更改为long 解决了这个问题,但我不明白为什么内存中的字节数在这里很重要。
这是一个示例输出
Thread 0 process 3 items
Thread 1 process 3 items
Thread 2 process 4 items
Get total items:4
PS:我确实知道这样做的正确方法是什么。 我不明白的是,当我将整数转换为指针然后将其存储在 4 字节内存中时会发生什么? 为什么可以打印出值但无法用它计算? 如果我使用 long(与 void* 大小相同)而不是 int(4 字节内存),那么一切正常的原因是什么?
【问题讨论】:
-
这一行:
int temp;应该是:int *temp = NULL;而这一行:total = total + temp;最好写成:total = total + *temp; -
这一行:
int chunk = ITEMS/THREADS;执行整数除法。这种说法有几个问题。一个明显的问题是,如果THREADS大于ITEMS,那么计算结果将为0。可能不是你想要的。 -
关于:
return end - start;有更好的方法可以退出线程函数。建议:int result = end-start; pthread_exit( (void*)&result ); -
调用:
pthread_create()时,始终检查返回值以确保操作成功。 IE。 if( 0 != pthread_create(...) ) { perror("pthread_create failed"); }
标签: c types casting pthreads pthread-join