简体   繁体   中英

c - can't understand pthread_join()

I can not figure out where I'm wrong, after running the code arrived in the for where it runs the pthread_join() , many pthread_join() return with value 3 instead of 0. Furthermore, printing the value of i is not always consistent and this causes segmentation fault and printing several times of the same position. Code modified as required in the comments all the includes are for other parts of the program. Testing only this piece of code creates segmentation fault at error 3 on pthread_join()

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>

#include <errno.h>
#include <config.h>
#include <sys/select.h>
#include <ctype.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <sys/un.h>

void *threadF(){
    printf("hello\n");
    pthread_exit((void*)0);     
}




int main(int argc, char *argv[]) {

    FILE *fileconf=fopen(argv[2],"r"); 
    if(fileconf==NULL){
        fprintf(stderr, "Fopen\n",argv[2]);
        return -1;
    }
    set_conf(fileconf); //parse fileconf and set THREADSINPOOL correctly

    pthread_t array[THREADSINPOOL];
    int i,err,s=0;
    for(i=0;i<THREADSINPOOL;i++){
        if((err=pthread_create(&array[i],NULL,&threadF,NULL))!=0){
            fprintf(stderr,"thread\n");
            exit(errno);
        }
    }

    int tmp;

    for(i=0;i<THREADSINPOOL;i++){
        tmp=pthread_join(array[i],(void *)&s);
        printf("thread: %lu terminated\n tmp: %d\n",array[i],tmp);
    }

    return 0;
}

The problem is that you are passing the address of an int to a function that expects the address of a void * . On a 64-bit system, there's a good chance that an int is only 32-bits whereas a void * is 64-bits. So pthread_join ends up writing 64-bits into a location that is only big enough for 32-bits. The result is that you overwrite memory that shouldn't being changed, and all sorts of undefined behavior follows.

Here's a way to write the code so that the second argument to pthread_join is actually a pointer to a void *

for (i = 0; i < THREADSINPOOL; i++)
{
    void *value;
    if (pthread_join(array[i], &value) == 0)
        printf("thread %d returned %" PRIiPTR "\n", i, (intptr_t)value);
    else
        printf("thread %d failed\n", i);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM