0

同期の小さな問題を解決しようとしています。しかし、スレッドに参加すると、5回目の反復でセグメント違反が発生します! 4 つのスレッドのみを作成すると、完璧に動作します。

ここでは、スレッドを実行するための基本的なコードをいくつか残します。

#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;
}

で実行:./work -h 4 -e 0 -b 1

それらは以下で実行されます:./work -h 5 -e 0 -b 1

「-h」の値を 4 以上に増やすと、セグメンテーション違反が発生します

なぜこれ?

4

2 に答える 2

3

s の配列の割り当てがpthread_t正しくありません。インスタンスの配列にストレージを割り当てたいpthread_tが、現在はポインター用のスペースしか割り当てていません。

正しい型にスペースを割り当てないと、後でこの配列に書き込むときに、割り当てられたメモリの終わりを超えて書き込む危険があります。これには未定義の結果があります。この場合、プログラムの他の部分で使用されるメモリを上書きする可能性があります。これにより、セグメンテーション違反が発生する可能性があります。

次のように割り当てを変更する必要があります

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

同じ問題が、次のように割り当てる必要があるparam配列にも当てはまりますvar

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

freeプログラムの後半でこれらの配列を使用することをお勧めします。

for (i=0; i<E+H; i++){
    pthread_join(bank[i], NULL);
    printf("join %i\n", i);
}
free(bank);
free(var);
于 2013-10-25T16:00:37.617 に答える