Question

I'm trying to solve a small problem of synchronization. but when I join the threads i get segment fault of the fifth iteration! If i only create 4 threads works perfect.

Here I leave the code with some basics of what to do the thread.

#include <stdio.h>              
#include <stdlib.h>             
#include <string.h>             
#include <pthread.h>            
#include <semaphore.h>

sem_t HackersEmploy_Counter;
int hackerOnBoat, employOnBoat, B, b, hackerResagado, employResagado;

sem_t Board;
int onBoatId[4];     
char onBoatType[4]; 

sem_t Bote;  

typedef struct{
    FILE* log;
    int ID;
}param;

void* HackerArrive(void* para){
    param* var = (param*) para;
    printf("Create Hacker %i\n", var->ID-1);
    pthread_exit(0);
}

void* EmployeeArrive(void* para){
    param* var = (param*) para;
    printf("Create Employee %i\n", var->ID-1);
    pthread_exit(0);
}

int main(int argc, char **argv) {
    sem_init(&HackersEmploy_Counter,0,1);
    sem_init(&Bote,0,4);
    sem_init(&Board,0,1);
    FILE* log;
    log = fopen("result_simulacion.txt", "w");
    int E, e=1, H, h=1, i, r;
    hackerOnBoat=0; employOnBoat=0; b=1; hackerResagado=0; employResagado=0;
    for (i=1; i<argc; i++){
        if (strcmp(argv[i],"-h")==0){
            i++;
            H = atoi(argv[i]);
        }
        if (strcmp(argv[i],"-e")==0){
            i++;
            E = atoi(argv[i]);
        }
        if (strcmp(argv[i],"-b")==0){
            i++;
            B = atoi(argv[i]);
        }
    }
    pthread_t* bank = (pthread_t*) malloc( (E+H) * sizeof (pthread_t*));
    param* var = (param*) malloc( (E+H) + sizeof (param*));
    for (i=0; i<H+E; i++){
        r = rand() % 2;
        if (r==0){
            if (h<=H){
                var[i].log = log;
                var[i].ID = h;
                pthread_create(&bank[i], NULL, HackerArrive, (void*) &var[i]);
                h++;
            }else{
                var[i].log = log;
                var[i].ID = e;
                pthread_create(&bank[i], NULL, EmployeeArrive, (void*) &var[i]);
                e++;
            }
        }else{
            if (e<=E){
                var[i].log = log;
                var[i].ID = e;
                pthread_create(&bank[i], NULL, EmployeeArrive, (void*) &var[i]);
                e++;
            }else{
                var[i].log = log;
                var[i].ID = h;
                pthread_create(&bank[i], NULL, HackerArrive, (void*) &var[i]);
                h++;
            }
        }
    }
    for (i=0; i<E+H; i++){
        pthread_join(bank[i], NULL);
        printf("join %i\n", i);
    }
    return 0;
}

run with: ./work -h 4 -e 0 -b 1

them run with: ./work -h 5 -e 0 -b 1

if they increase the value of "-h" more than 4 receive segmentation fault

Why this?

Était-ce utile?

La solution 2

Please be more careful reading your code. This:

param* var = malloc((E+H) + sizeof(*var));

should be this:

param* var = malloc((E+H) * sizeof(*var));
//                        ^

Your code works (or at least, doesn't crash) for me after this change:

paul@local:~/src/c/scratch$ ./thread -h 2 -e 2 -b 2
Create Employee 0
Create Hacker 1
Create Employee 1
Create Hacker 0
join 0
join 1
join 2
join 3
paul@local:~/src/c/scratch$

Using a tool like valgrind would have helped you track this one down in minutes.

As mentioned in my other comment, you should check the return every single time you call functions like malloc(), fopen(), pthread_create(), pthread_join(), and so on, otherwise you have absolutely no idea whether you're ignoring important errors your functions are trying to tell you about.

Autres conseils

The allocation for your array of pthread_ts isn't quite right. You want to allocate storage for an array of pthread_t instances but are currently only allocating space for pointers.

By not allocating space for the correct type, you risk writing beyond the end of your allocated memory when you later write to this array. This has undefined consequences; in this case you're likely to over-write memory used by other parts of your program. This may well cause a segfault.

You should change the allocation as follows

pthread_t* bank = malloc((E+H) * sizeof(*bank));

The same issue applies to the param array var which should be allocated like

param* var = malloc((E+H) + sizeof(*var));

Note that it'd be good practice for you to free these arrays later in your program

for (i=0; i<E+H; i++){
    pthread_join(bank[i], NULL);
    printf("join %i\n", i);
}
free(bank);
free(var);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top