Seg Fault до появления основного - PullRequest
0 голосов
/ 05 мая 2020

Я новичок в C, но я продолжаю получать эту ошибку сегментации перед основным, и я не знаю, почему, я бы спросил своего профессора, но она занята другими делами, связанными с банкоматом, чтобы беспокоиться о чем-то столь тривиальном, как это.

Здесь полный код:

Любая помощь будет принята с благодарностью.

РЕДАКТИРОВАТЬ: Я верю, что это ошибка seg перед основным, потому что я поместил оператор печати в первую строку main, и он дал сбой перед этой строкой.

Я компилирую с gcc program.c -o prog -lpthread -DUNIX и запускаю его в подсистеме Ubuntu для windows, но у меня никогда раньше не было этой проблемы с ним.

/***** Includes *****/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//Linux or MacOS
#ifdef UNIX
    #include <pthread.h>
    #include <unistd.h>
#endif

//Windows
#ifdef WINDOWS
    #include <windows.h>
#endif

/***** Defines: Constants in seconds *****/
#define PRODUCER_SLEEP_S    1
#define CONSUMER_SLEEP_S    1
#define QUEUESIZE           5
#define LOOP                10


/***** Function prototypes *****/
void *producer (void *args);
void *consumer (void *args);

/***** Queue struct *****/
typedef struct 
{
    int buf[QUEUESIZE];
    long head, tail;
    int full, empty; 
    pthread_mutex_t* mutex;
    pthread_cond_t *nextCon;
    pthread_cond_t *nextProd;

    //mutex 1= free
    //mutex 2= taken
    //you may need or may not
    /*TODO for students: Declare the locks here */
} queue;

/***** Queue function prototypes  *****/
queue *queueInit (void);
void queueDelete (queue *q);
void queueAdd (queue *q, int in);
void queueDel (queue *q, int *out);

/***** main *****/
int main ()
{
//does not reach this point

   printf("test");

    queue *fifo;
    int i;

    //for Consumer's random coming
    unsigned int iseed = (unsigned int)time(NULL);
    //seeds the random number generator
    srand(iseed);

    /******one producer and multiple consumer********/

    //an array of consumers and one producer
    #ifdef UNIX
    pthread_t pro, con[LOOP];
    #endif

    //an array of consumers and one producer
    #ifdef WINDOWS
    HANDLE pro, con[LOOP];
    #endif

    fifo = queueInit ();
    if (fifo ==  NULL) 
    {
        fprintf (stderr, "main: Queue Init failed.\n");
        exit (1);
    }

    #ifdef UNIX
        pthread_create (&pro, NULL, producer, fifo);
        for(i=0; i<LOOP; i++)
        {
            pthread_create (&con[i], NULL, consumer, fifo);
        }
    #endif

    #ifdef WINDOWS
        pro = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) producer, fifo, 0, NULL);
        for(i=0; i<LOOP; i++)
        {
    #ifdef WINDOWS
            /* TODO for students: Simulate Consumers' random arrival */
            Sleep((rand()%2)*1000);
    #endif
            con[i] = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) consumer, fifo, 0, NULL);        
        }
    #endif


    #ifdef UNIX
        pthread_join (pro, NULL);
        for(i=0; i<LOOP; i++)
        {
            pthread_join (con[i], NULL);    
        }
    #endif

    #ifdef WINDOWS
        WaitForSingleObject(pro, INFINITE);
        /*******Wait for all the threads complete**********/      
        WaitForMultipleObjects(LOOP, con, TRUE, INFINITE);  

    #endif

    queueDelete (fifo);

    #ifdef WINDOWS
    system("pause");
    #endif

    return 0;
}

/***** producer *****/
void *producer (void *q)
{

    queue *fifo;
    int i;

    fifo = (queue *)q;

    //TODO for students: obtain the lock and release the lock somewhere

    for (i = 0; i < LOOP; i++) 
    {

        // TODO for students: Obtain the locks somewhere here

        #ifdef UNIX
        pthread_mutex_lock(fifo->mutex);
        while (fifo->full) 
        {
            pthread_cond_wait(fifo->nextProd, fifo->mutex);
        }
        #endif

        #ifdef WINDOWS

        #endif


        queueAdd (fifo, i+1);
        printf ("producer: produced %d th.\n",i+1);
        /* sleep */
        #ifdef UNIX
            usleep ( PRODUCER_SLEEP_S * 1000000); 
        #endif

        #ifdef WINDOWS
            Sleep ( PRODUCER_SLEEP_S * 1000);   
        #endif

        /*******Release the locks**********/
        #ifdef UNIX
         pthread_cond_signal(fifo->nextCon);
            pthread_mutex_unlock(fifo->mutex);
        #endif


        #ifdef WINDOWS

        #endif
    }

    return (NULL);
}

/***** consumer *****/
void *consumer (void *q)
{
    queue *fifo;
    int d;

    fifo = (queue *)q;

    /* Simulate Consumers' random arrival */
    #ifdef UNIX
        usleep ( (rand()%LOOP) * 1000000); 
    #endif


    // TODO for students: obtain the lock and release the lock somewhere

    #ifdef UNIX
    pthread_mutex_lock(fifo->mutex);
    while (fifo->empty) 
    {
        pthread_cond_wait(fifo->nextCon, fifo->mutex);
    }
    #endif


    #ifdef WINDOWS

    #endif

    /* sleep */
    #ifdef UNIX
        usleep ( CONSUMER_SLEEP_S * 1000000); 
    #endif

    #ifdef WINDOWS
        Sleep ( CONSUMER_SLEEP_S * 1000);   
    #endif


    queueDel (fifo, &d);
    printf ("------------------------------------>consumer: recieved %d.\n", d);        

    #ifdef UNIX
        pthread_cond_signal(fifo->nextProd);
        pthread_mutex_unlock(fifo->mutex);
    #endif


    #ifdef WINDOWS

    #endif


    return (NULL);
}


/***** queueInit *****/
queue *queueInit (void)
{
    queue *q;
    int i;

    q = (queue *)malloc (sizeof (queue));
    if (q == NULL) return (NULL);

    for(i=0;i<QUEUESIZE;i++)
    {
        q->buf[i]=0;
    }
    q->empty = 1;
    q->full = 0;
    q->head = 0;
    q->tail = 0;
    //TODO for students: Initialize the locks here
    pthread_mutex_init(q->mutex,NULL);
    pthread_cond_init(q->nextCon,NULL);
    pthread_cond_init(q->nextProd,NULL);
    return (q);
}


/***** queueDelete *****/
void queueDelete (queue *q)
{

    //TODO for students: free the locks here

    pthread_mutex_destroy(q->mutex);
    /* free memory used for queue */
    free (q);
}

/***** queueAdd *****/
void queueAdd (queue *q, int in)
{
    q->buf[q->tail] = in;
    q->tail++;
    if (q->tail == QUEUESIZE)
        q->tail = 0;
    if (q->tail == q->head)
        q->full = 1;
    q->empty = 0;

    return;
}

/***** queueDel *****/
void queueDel (queue *q, int *out)
{
    *out = q->buf[q->head];
    q->buf[q->head]=0;

    q->head++;

    if (q->head == QUEUESIZE)
        q->head = 0;
    if (q->head == q->tail)
        q->empty = 1;
    q->full = 0;

    return;
}



Ответы [ 2 ]

1 голос
/ 05 мая 2020

РЕДАКТИРОВАТЬ: Я полагаю, что это ошибка seg перед main, потому что я поместил оператор печати в первую строку main, и он дал сбой перед этой строкой.

Как объясняли другие, это недопустимый метод устранения неполадок, ваша ошибка sh появится намного позже.

   pthread_mutex_t* mutex;

Хорошо, поэтому mutex - это указатель на мьютекс, который не имеет определенного значения.

pthread_mutex_init(q->mutex,NULL);

И вы не передаете это конкретное значение в pthread_mutex_init. Неудивительно, что он вылетает. Вы должны были передать указатель на мьютекс, который нужно инициализировать, а не указатель, который ни на что не указывает.

0 голосов
/ 05 мая 2020

Это трассировка gdb, в ней не говорится, что ошибка сегментации возникает до main (), но после main (), немного после вызова queueInit ():

#1  0x0000555555555726 in queueInit () at seg.c:259
#2  0x00005555555553d1 in main () at seg.c:77

Фактически, В задании есть несколько примечаний, помеченных "TODO", я хотел бы привлечь ваше внимание к этой части и многим другим подобным:

//TODO for students: Initialize the locks here
...