[英]C, pthreads initialized in loop does not execute assigned function properly despite mutex
I am having trouble debugging my C program where the goal is to create 5 threads and have each of them working on size-2 chunks of an array of length 10. The goal is to get the sum of that array. 我在调试C程序时遇到了麻烦,该程序的目标是创建5个线程,并使每个线程在长度为10的数组的size-2块上工作。目标是获取该数组的总和。 My actual program is a little less trivial than this as it takes dynamic array sizes and thread counts but I tried simplifying it to this simple problem and it still does not work.
我的实际程序比这要简单一些,因为它需要动态数组大小和线程数,但是我尝试将其简化为这个简单的问题,但仍然无法正常工作。
ie., 即,
array = {1 2 3 4 5 6 7 8 9 10} 数组= {1 2 3 4 5 6 7 8 9 10}
then thread1 works on array[0] and array [1] 然后线程1在数组[0]和数组[1]上工作
and thread2 works on array[2] and array[3] 和thread2适用于array [2]和array [3]
etc... 等等...
thread5 works on array[8] and array[9] thread5适用于array [8]和array [9]
However when i run my code, I get weird results, even when using a mutex lock. 但是,当我运行代码时,即使使用互斥锁,也会得到奇怪的结果。
For example, this is one of my results when running this program. 例如,这是运行该程序时的结果之一。
Thread #1 adding 3 to 0 New sum: 3
Thread #1 adding 4 to 3 New sum: 7
Thread #2 adding 5 to 7 New sum: 12
Thread #2 adding 6 to 12 New sum: 18
Thread #3 adding 7 to 18 New sum: 25
Thread #3 adding 8 to 25 New sum: 33
Thread #4 adding 9 to 33 New sum: 42
Thread #4 adding 9 to 42 New sum: 51
Thread #4 adding 10 to 51 New sum: 61
Thread #4 adding 10 to 61 New sum: 71
Sum: 71
First of all, why are there no tabs before the "New sum" for the first 3 lines? 首先,为什么前三行的“新总和”之前没有选项卡? (see my printf log in calculate_sum function).
(请参阅calculate_sum函数中的printf日志)。 And more importantly, why is thread0 never executing it's job and why is thread 4 executing twice?
更重要的是,为什么线程0永远不执行其工作,为什么线程4执行两次?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct {
int start, end, thread_number;
int *data;
} Func_args;
static pthread_mutex_t mutex;
static int sum = 0;
void *calculate_sum(void *args) {
int *arr = ((Func_args *)args)->data;
int i = ((Func_args *)args)->start;
int end = ((Func_args *)args)->end;
int t_id = ((Func_args *)args)->thread_number;
while (i < end) {
pthread_mutex_lock(&mutex);
printf("Thread #%d adding %d to %d\t", t_id, arr[i], sum);
sum += arr[i++];
printf("New sum: %d\n", sum);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
#define NUM_THREAD 5
#define ARRAY_LEN 10
int main(int argc, char **argv) {
int array[ARRAY_LEN] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
pthread_t tid[NUM_THREAD];
int i, pos = 0;
pthread_mutex_init(&mutex, NULL);
for (i = 0; i < NUM_THREAD; i++) {
Func_args args;
args.data = array;
args.thread_number = i;
args.start = pos;
pos += 2;
args.end = pos;
pthread_create(&tid[i], NULL, calculate_sum, &args);
}
for (i = 0; i < NUM_THREAD; i++)
pthread_join(tid[i], NULL);
pthread_mutex_destroy(&mutex);
printf("Sum: %d\n", sum);
return 0;
}
You are passing each thread a pointer to an object that might get destroyed before the thread starts. 您正在向每个线程传递一个指向对象的指针,该对象可能在线程启动之前被破坏。
args
is local, so it gets destroyed when the program exits the scope it's declared in - that is, at the end of the for
loop body. args
是本地的,因此当程序退出在其中声明的范围时(即,在for
循环主体的末尾),它将被销毁。
The thread might takes a few moments to start up, so if the thread starts after that, it will access a destroyed object - in practice, the memory will have been reused to store the next thread's values. 该线程可能需要一些时间才能启动,因此如果该线程在此之后启动,它将访问一个被破坏的对象-实际上,该内存将被重用于存储下一个线程的值。
You can fix it by dynamically allocating the thread data with malloc
(and remembering to free
it in the thread or if pthread_create fails). 您可以通过使用
malloc
动态分配线程数据(并记住在线程中free
它,或者记住如果pthread_create失败)来修复它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.