簡體   English   中英

分段故障(核心轉儲)錯誤消息

[英]segmentation fault(core dumped) error message

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

pthread_mutex_t mutex_lock;

/* semaphore declarations */
sem_t students_sem; /* ta waits for a student to show up, student notifies ta his/her arrival */
sem_t ta_sem;       /* students waits for ta to help, ta notifies student he/she is ready to help */

/* the number of waiting students */
int waiting_students;

/* ta sleeping status indicator */
int ta_sleep = 1;
/* the maximum time (in seconds) to sleep */
#define MAX_SLEEP_TIME 3 

/* number of potential students */
#define NUM_OF_STUDENTS 4

#define NUM_OF_HELPS 2

/* number of available seats */
#define NUM_OF_SEATS 2

/* Student IDs */
int stud_id[NUM_OF_STUDENTS];

/* TA and student threads */
pthread_t students_thread[NUM_OF_STUDENTS];
pthread_t ta_thread;

/* function prototype */
void* ta_check(void* p);
void* student_check(void* p);

int main (void) 
{
    /* local variable declaration */
    int i;

    /* initialize mutex and semaphore */
    pthread_mutex_init(&mutex_lock, NULL);
    sem_init(&ta_sem, 0, 0);
    sem_init(&students_sem,0,0);

    /* create ta thread */
    pthread_create(&ta_thread, 0, ta_check,0);

    /* create student threads */
    for (i = 0; i < NUM_OF_STUDENTS; i++)
        pthread_create(&students_thread[i], 0, student_check,(void*)&stud_id[i]);

    /* join student threads */
    for (i = 0; i < NUM_OF_STUDENTS; i++)
        pthread_join(students_thread[i], NULL);

    /* cancel ta thread when all student threads terminate */
    pthread_cancel(ta_thread);
    printf("The TA finished helping all students.\n");

    return 0;
}

void* ta_check(void* p)
{
    /* invoke random number generator */
    rand_r(time(NULL));
    while (1)
    {
        pthread_mutex_lock(&mutex_lock);
        ta_sleep = 1;
        pthread_mutex_unlock(&mutex_lock);
        sem_wait(&students_sem);
        // help a student 
        printf("Helping a student for %d seconds, # of waiting students = %d", MAX_SLEEP_TIME, waiting_students);
        sleep(MAX_SLEEP_TIME);
        // check if there are more student to help
        while (waiting_students > 0)
        {
            sem_post(&ta_sem);
            pthread_mutex_lock(&mutex_lock);
            waiting_students--;
            pthread_mutex_unlock(&mutex_lock);
            // help student
            printf("Helping a student for %d seconds, # of waiting students = %d", MAX_SLEEP_TIME, waiting_students);
            sleep(MAX_SLEEP_TIME);
        }
    }
    return NULL;
}

void* student_check(void* p)
{
    /* invoke random number generator */
    rand_r((unsigned*)1);
    int num_help = 0;
    int seat_taken = 0;

    while (num_help <= NUM_OF_HELPS)
    {
        // check if ta is not sleeping 
        if (!ta_sleep)
        {
            if (!seat_taken)
            {
                if (waiting_students < NUM_OF_SEATS)
                {
                    // student take a seat
                    seat_taken = 1;
                    pthread_mutex_lock(&mutex_lock);
                    waiting_students++;
                    pthread_mutex_unlock(&mutex_lock);
                    printf("Stdudent %d takes a seat, # of waiting student = %d", *(int*)p, waiting_students);
                    sem_wait(&ta_sem); 
                    seat_taken = 0;
                    num_help++;
                }
                else
                {
                    printf("\tStudent %d programming for %d seconds\n",*(int*)p,MAX_SLEEP_TIME);
                    sleep(MAX_SLEEP_TIME);
                    printf("\tStudent %d will try later\n",*(int*)p);
                }
            }
        }
        // check if ta is sleeping
        else if (ta_sleep)
        {
            pthread_mutex_lock(&mutex_lock);
            ta_sleep = 0;
            pthread_mutex_unlock(&mutex_lock);
            sem_post(&students_sem);
            sem_wait(&ta_sem);
            num_help++;
        }
    }
    printf("Student %d is receiving help", *(int*)p);
    return NULL;
}

為該程序修復所有錯誤和警告消息后,我第一次遇到此錯誤消息segmentation fault(core dumped) 在調試該程序之前,它從未出現過。 我可以在查找此錯誤發生的位置上獲得一些幫助。 非常感謝您的幫助。

rand_r函數需要一個指向unsigned int的指針(用法不同於rand

因此,您應該執行以下操作:

unsigned int myrand = (unsigned int)time(NULL);
rand_r(&myrand);

當我在gdb運行它時,我看到有關rand_r()的投訴:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff77f6700 (LWP 6018)]
rand_r (seed=0x5639d757) at rand_r.c:31
31  rand_r.c: No such file or directory.
(gdb) bt 
#0  rand_r (seed=0x5639d757) at rand_r.c:31
#1  0x0000000000400af7 in ta_check (p=0x0) at foo.c:71
#2  0x00007ffff7bc4182 in start_thread (arg=0x7ffff77f6700) at pthread_create.c:312
#3  0x00007ffff78f147d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

這是您的問題:rand_r((unsigned *)1)(也rand_r(time(NULL))

每當您發現自己將字面量轉換為指針(並且您沒有在進行深度嵌入的編程)時,您都應該會感到懷疑(而在編寫驅動程序時,您應該是偏執狂)。

在這種情況下,rand_r寫入指針所指向的內存,因此它必須是每個線程的整數,而不是文字。

rand_r(time(NULL)不會段錯誤,但也不會按您期望的那樣工作,因為實際上您每次調用該事物時都使用當前時間為RNG重新播種(我希望RNG輸出在此每秒精確地更改一次)案件)。

最簡單的方法可能是使學生和TA具有較小的結構,並且每個都包含一個int rand_state,您可以在啟動線程(初始種子)之前使用隨機值對其進行初始化,然后調用rand_r(&student-> rand_state)將為您提供結果你期望的。 這些結構還可以包含學生或TA的pthread。

問候,丹。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM