简体   繁体   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;
}

After I finished fixings all errors and warnings messages for this program, I encountered this error message segmentation fault(core dumped) for the first time. 为该程序修复所有错误和警告消息后,我第一次遇到此错误消息segmentation fault(core dumped) It has never appear before I was debugging this program. 在调试该程序之前,它从未出现过。 Can I get some help with finding where this error occurred. 我可以在查找此错误发生的位置上获得一些帮助。 Thank you very much for helping. 非常感谢您的帮助。

The rand_r function needs a pointer to an unsigned int (not the same usage than rand . rand_r函数需要一个指向unsigned int的指针(用法不同于rand

So you should do: 因此,您应该执行以下操作:

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

When I run it in gdb , I see a complaint about rand_r() : 当我在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

This is your problem: rand_r((unsigned*)1) (Also rand_r(time(NULL)) 这是您的问题:rand_r((unsigned *)1)(也rand_r(time(NULL))

Any time you find yourself casting a literal to a pointer (and you are not doing deeply embedded programming) you should be suspicious (And when you are writing drivers you should be paranoid instead). 每当您发现自己将字面量转换为指针(并且您没有在进行深度嵌入的编程)时,您都应该会感到怀疑(而在编写驱动程序时,您应该是偏执狂)。

In this instance, rand_r WRITES to the memory pointed to by the pointer so this needs to be a per thread int, not a literal. 在这种情况下,rand_r写入指针所指向的内存,因此它必须是每个线程的整数,而不是文字。

rand_r(time(NULL) will not segfault but also will not work as you expect because you are in effect re seeding the RNG with the current time every time you call the thing (I expect the RNG output to change precisely once a second in this case). rand_r(time(NULL)不会段错误,但也不会按您期望的那样工作,因为实际上您每次调用该事物时都使用当前时间为RNG重新播种(我希望RNG输出在此每秒精确地更改一次)案件)。

Easiest thing might be to make the students and TAs small structures and have each contain an int rand_state which you can initialise with random values before starting the threads (The initial seeds), then calling rand_r (&student->rand_state) will give you the result you expect. 最简单的方法可能是使学生和TA具有较小的结构,并且每个都包含一个int rand_state,您可以在启动线程(初始种子)之前使用随机值对其进行初始化,然后调用rand_r(&student-> rand_state)将为您提供结果你期望的。 These structures could also contain the pthread for the student or TA. 这些结构还可以包含学生或TA的pthread。

Regards, Dan. 问候,丹。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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