C中的线程安全队列出现分段错误
我是C语言的新手,甚至对多线程和尝试创建线程安全队列数据结构更是新手。它在dequeue()中的第116行出现seg错误(代码中有注释),我想知道是否有人能看到我的实现中存在任何明显的问题。非常感谢C中的线程安全队列出现分段错误,c,multithreading,data-structures,queue,C,Multithreading,Data Structures,Queue,我是C语言的新手,甚至对多线程和尝试创建线程安全队列数据结构更是新手。它在dequeue()中的第116行出现seg错误(代码中有注释),我想知道是否有人能看到我的实现中存在任何明显的问题。非常感谢 typedef struct node{ char *data; struct node *next; } node; extern int directoryThreads; //unbounded queue for file and directory queue typed
typedef struct node{
char *data;
struct node *next;
} node;
extern int directoryThreads;
//unbounded queue for file and directory queue
typedef struct {
node *head;;
node *tail;
int activeThreads;
int open;
int count;
pthread_mutex_t lock;
pthread_cond_t read_ready;
//pthread_cond_t write_ready;
} queue_t;
char *dequeue(queue_t *Q)
{
pthread_mutex_lock(&Q->lock); //lock queue
if(isempty(Q)){
Q->activeThreads--;
if(Q->activeThreads == 0){
pthread_mutex_unlock(&Q->lock);
return NULL;
}
while (isempty(Q) && Q->activeThreads>0) {
pthread_cond_wait(&Q->read_ready, &Q->lock);
}
if (isempty(Q)){
pthread_mutex_unlock(&Q->lock);
return NULL;
}
Q->activeThreads++;
}
//printf("%s", "Dequeued: ");
//display(Q->head);
char *item = (char *) malloc(strlen(Q->head->data) + 1); //segault here
item = Q->head->data;
if(Q->count>1){
Q->head = Q->head->next;
}
else{
Q->head = NULL;
}
Q->count--;
pthread_mutex_unlock(&Q->lock);
return item;
}
问题在别处。(我没有排除导致竞争条件的信令协议问题,但我对此表示怀疑。稍后将对此进行详细说明。)
如果信号由Q->head->data
抛出,Q->head
包含垃圾,或者isempty(Q)
和Q->head!=NULL
不一致
如果信号是由strlen
抛出的,Q->head->data
包含垃圾,或者字符串没有正确以NUL结尾
这并不意味着
出列不存在任何问题
- 您在
出列
中无缘无故地分配内存
- 更糟糕的是,您在下一行覆盖了malloc返回的指针,导致内存泄漏
dequeue
永远不要更改Q->tail
,即使Q->head
为NULL
时它应该为NULL
- 信令协议过于复杂
固定的:
//当不再向队列添加任何内容时调用done()。
//这样做是为了取消阻止对出列的调用,并且
//以使未来的呼叫立即返回。
无效队列\u完成(队列\u t*Q){
pthread_mutex_lock(&Q->lock);
Q->done=1;
//如果另一个线程在dequeue()中被阻塞。
pthread_cond_信号(&Q->read_ready);
pthread_mutex_unlock(&Q->lock);
}
char*Queue\u dequeue(Queue\u t*Q){
pthread_mutex_lock(&Q->lock);
而(!Q->head&!Q->done)
pthread_cond_wait(&Q->read_ready,&Q->lock);
char*rv;
如果(Q->head){
rv=Q->head->data;
Q->head=Q->head->next;
如果(!Q->head)
Q->tail=NULL;
--Q->计数;
}否则{
//调用了done(),队列为空。
rv=NULL;
}
//如果另一个线程在dequeue()中被阻塞。
pthread_cond_信号(&Q->read_ready);
pthread_mutex_unlock(&Q->lock);
返回rv;
}
示例程序:
静态队列;
无效消费者(无效){
而(1){
char*job=Queue\u dequeue(&Q);
如果(!作业)
打破
//用“工作”做点什么。
免费(工作);
}
}
内部主(空){
队列初始化(&Q);
//在这里创建使用者线程。
//在这里向队列添加内容。
//-或-
//创建生产者线程,在此处等待它们完成。
队列_完成(&Q);
//在此等待使用者线程完成。
队列销毁(&Q);
}
我以前有一个线程安全队列的演示实现。(不过,它使用固定大小的循环缓冲区,而不是链表。)