Pithikos / C-Thread-Pool

A minimal but powerful thread pool in ANSI C
MIT License
2.06k stars 603 forks source link

The execution result seems to be something wrong while I use the Thread pool? #98

Closed MisterDo closed 9 months ago

MisterDo commented 3 years ago
void fun1(int nums[],int start,int end){

    for(int i=start;i<end;i++){
        nums[i] = i;
    }
}

void task(void *arg){
    task_args task_args_val = *(task_args*)arg;
    fun1(task_args_val.nums,task_args_val.start,task_args_val.end);

}

int main(){
    int thread_num = 2;
    int nums_len = 20;
    int range = nums_len/thread_num;
    threadpool thpool = thpool_init(thread_num);
    int nums[20] = {0};

    for(int i=0;i<thread_num;i++){
        int start = i*range;
        int end = (i+1)*range;
        if(i==thread_num){
            end = nums_len;
        }
        task_args task_args_val;
        task_args_val.nums = nums;
        task_args_val.start = start;
        task_args_val.end = end;
        thpool_add_work(thpool,task,(void *)&task_args_val);

    }
    thpool_wait(thpool);
    thpool_destroy(thpool);
    puts("Killing threadpool");
    for(int i=0;i<nums_len;i++){
        printf("nums[%d]=%d\n",i,nums[i]);
    }

    return 0;
}

The some elements of the array are not assigned values? nums[0]=0 nums[1]=0 nums[2]=0 nums[3]=0 nums[4]=0 nums[5]=0 nums[6]=0 nums[7]=0 nums[8]=8 nums[9]=9 nums[10]=0 nums[11]=0 nums[12]=12 nums[13]=13 nums[14]=0 nums[15]=0 nums[16]=16 nums[17]=17 nums[18]=18 nums[19]=19 ......

swofford commented 1 year ago

I realize this was posted over two years ago...just trying to help the maintainers close out some issues.

The result you are getting is due to a bug in your code and not with C-Thread-Pool. You are using the same task_args struct copy for both threads, rather than using separate memory for each thread. The first thread task starts before the start and end members have been reset to 10 and 20, respectively, , which is why only a couple of the num elements <10 are set to nonzero values.

You can easily verify this by replacing your loop with the following:

    task_args args[2];
    for(int i=0;i<thread_num;i++){
        int start = i*range;
        int end = (i+1)*range;
        if(i==thread_num){
            end = nums_len;
        }
        args[i].nums = nums;
        args[i].start = start;
        args[i].end = end;
        thpool_add_work(thpool,task,(void *)&args[i]);        
    }

Now, since each thread uses a different task_args struct, the program outputs the expected result.