C中的线程安全队列出现分段错误

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

我是C语言的新手,甚至对多线程和尝试创建线程安全队列数据结构更是新手。它在dequeue()中的第116行出现seg错误(代码中有注释),我想知道是否有人能看到我的实现中存在任何明显的问题。非常感谢

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);
}

我以前有一个线程安全队列的演示实现。(不过,它使用固定大小的循环缓冲区,而不是链表。)