主要发生之前的段错误
Seg Fault before main occurs
我对 C 有点陌生,但我在 main 之前一直遇到这个分段错误,我不知道为什么,我会问我的教授,但她正忙于其他事情 ATM 担心像这样微不足道的事情。
这里是完整代码:
如有任何帮助,我们将不胜感激。
编辑:我认为它在 main 之前出现段错误,因为我在 main 的第一行放置了一个打印语句,但它在该行之前出现了错误。
我正在 windows 的 Ubuntu 子系统上使用 gcc program.c -o prog -lpthread -DUNIX
和 运行 进行编译,但我以前从未遇到过这个问题。
/***** 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;
}
这是gdb的backtrace,它并没有说段错误发生在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
EDIT: I beleive it is seg faulting before main because I have put a print statement on the first line of main and it faulted before that line.
正如其他人所解释的那样,这不是一种有效的故障排除技术,您的崩溃会晚得多。
pthread_mutex_t* mutex;
好的,所以 mutex
是指向没有特定值的互斥量的指针。
pthread_mutex_init(q->mutex,NULL);
然后您将这个没有特定值的值传递给 pthread_mutex_init
。难怪它会崩溃。你应该传递一个指向你想要初始化的互斥体的指针,而不是一个不指向任何东西的指针。
我对 C 有点陌生,但我在 main 之前一直遇到这个分段错误,我不知道为什么,我会问我的教授,但她正忙于其他事情 ATM 担心像这样微不足道的事情。
这里是完整代码:
如有任何帮助,我们将不胜感激。
编辑:我认为它在 main 之前出现段错误,因为我在 main 的第一行放置了一个打印语句,但它在该行之前出现了错误。
我正在 windows 的 Ubuntu 子系统上使用 gcc program.c -o prog -lpthread -DUNIX
和 运行 进行编译,但我以前从未遇到过这个问题。
/***** 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;
}
这是gdb的backtrace,它并没有说段错误发生在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
EDIT: I beleive it is seg faulting before main because I have put a print statement on the first line of main and it faulted before that line.
正如其他人所解释的那样,这不是一种有效的故障排除技术,您的崩溃会晚得多。
pthread_mutex_t* mutex;
好的,所以 mutex
是指向没有特定值的互斥量的指针。
pthread_mutex_init(q->mutex,NULL);
然后您将这个没有特定值的值传递给 pthread_mutex_init
。难怪它会崩溃。你应该传递一个指向你想要初始化的互斥体的指针,而不是一个不指向任何东西的指针。