分段错误(核心转储)错误消息
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)
。在我调试这个程序之前它从来没有出现过。我可以得到一些帮助来查找发生此错误的位置吗?非常感谢您的帮助。
当我 运行 它在 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 int 的指针(与 rand
的用法不同。
所以你应该这样做:
unsigned int myrand = (unsigned int)time(NULL);
rand_r(&myrand);
这是你的问题:rand_r((unsigned*)1)(还有 rand_r(time(NULL))
任何时候你发现自己将文字转换为指针(并且你没有进行深度嵌入式编程)你应该怀疑(而当你编写驱动程序时你应该偏执)。
在这种情况下,rand_r 写入指针指向的内存,因此这需要是每个线程的 int,而不是文字。
rand_r(time(NULL) 不会出现段错误,但也不会像您预期的那样工作,因为您实际上每次调用时都会用当前时间重新播种 RNG(我希望 RNG在这种情况下,输出精确地每秒更改一次。
最简单的方法可能是将学生和助教制作成小型结构,并让每个结构都包含一个 int rand_state,您可以在启动线程(初始种子)之前用随机值对其进行初始化,然后调用 rand_r (&student->rand_state) 会给你你期望的结果。
这些结构还可以包含学生或助教的 pthread。
问候,丹。
#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)
。在我调试这个程序之前它从来没有出现过。我可以得到一些帮助来查找发生此错误的位置吗?非常感谢您的帮助。
当我 运行 它在 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 int 的指针(与 rand
的用法不同。
所以你应该这样做:
unsigned int myrand = (unsigned int)time(NULL);
rand_r(&myrand);
这是你的问题:rand_r((unsigned*)1)(还有 rand_r(time(NULL))
任何时候你发现自己将文字转换为指针(并且你没有进行深度嵌入式编程)你应该怀疑(而当你编写驱动程序时你应该偏执)。
在这种情况下,rand_r 写入指针指向的内存,因此这需要是每个线程的 int,而不是文字。
rand_r(time(NULL) 不会出现段错误,但也不会像您预期的那样工作,因为您实际上每次调用时都会用当前时间重新播种 RNG(我希望 RNG在这种情况下,输出精确地每秒更改一次。
最简单的方法可能是将学生和助教制作成小型结构,并让每个结构都包含一个 int rand_state,您可以在启动线程(初始种子)之前用随机值对其进行初始化,然后调用 rand_r (&student->rand_state) 会给你你期望的结果。 这些结构还可以包含学生或助教的 pthread。
问候,丹。