Linux多线程12-生产者和消费者模型
一个最简单的生产者消费者模型
/*
生产者消费者模型(粗略版)
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
struct Node{
int num;
struct Node* next;
};
//头节点
struct Node* head = NULL;
void* producer(void* arg){
//往容器中添加内容
//不断的创建新节点, 添加到链表中
while(1){
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode -> next = head;
head = newNode;
newNode -> num = rand()%1000;
printf("add node, num: %d, tid: %d\n", newNode->num, pthread_self())''
usleep(100);
}
return NULL;
}
void* customer(void* arg){
//从容器中消费内容
while(1){
//保存头节点指针
struct Node* tmp = head;
head = head->next;
printf("delete node, num: %d, tid: %ld\n", tmp->num, pthread_self());
free(tmp);
usleep(100);
}
return NULL;
}
int main(){
//5个生产者线程, 5个消费者线程
pthread_t ptid[5], ctid[5];
int i;
for(i=0; i<5; i++){
pthread_create(&ptid[i], NULL, producer, NULL);
pthread_create(&ctid[i], NULL, customer, NULL);
}
for(i=0; i<5; i++){
pthread_detach(ptid[i]);
pthread_detach(ctid[i]);
}
// while(1){
// sleep(10);
// }
pthread_exit(NULL);
return 0;
}
问题:
-
Segmentation fault (core dumped) 段错误
生成core文件
$ ulimit -a core file size (blocks, -c) 0 $ ulimit -c unlimited $ ulimit -a core file size (blocks, -c) unlimited $ gcc producer.c -o producer -g -pthread $ ./producer Segmentation fault (core dumped)
-
查看错误
(gdb) core-file core [New LWP 2112] [New LWP 2110] [New LWP 2115] [New LWP 2113] [New LWP 2111] [New LWP 2114] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `./producer'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x0000000000400906 in customer (arg=0x0) at producer.c:37 37 head = head->next;
-
(如果head为空, 是无法访问head->next)
代码修改:
/*
生产者消费者模型(粗略版)
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
//创建互斥量
pthread_mutex_t mutex;
struct Node{
int num;
struct Node* next;
};
//头节点
struct Node* head = NULL;
void* producer(void* arg){
//往容器中添加内容
//不断的创建新节点, 添加到链表中
while(1){
pthread_mutex_lock(&mutex);
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode -> next = head;
head = newNode;
newNode -> num = rand()%1000;
printf("add node, num: %d, tid: %ld\n", newNode->num, pthread_self());
pthread_mutex_unlock(&mutex);
usleep(100);
}
return NULL;
}
void* customer(void* arg){
//从容器中消费内容
while(1){
pthread_mutex_lock(&mutex);
//保存头节点指针
struct Node* tmp = head;
//判断是否还有数据
if(head!=NULL){
head = head->next;
printf("delete node, num: %d, tid: %ld\n", tmp->num, pthread_self());
free(tmp);
pthread_mutex_unlock(&mutex);
usleep(100);
}else{
//没有数据就解锁,防止又回去重复加锁,导致死锁
pthread_mutex_unlock(&mutex);
}
}
return NULL;
}
int main(){
pthread_mutex_init(&mutex, NULL);
//5个生产者线程, 5个消费者线程
pthread_t ptid[5], ctid[5];
int i;
for(i=0; i<5; i++){
pthread_create(&ptid[i], NULL, producer, NULL);
pthread_create(&ctid[i], NULL, customer, NULL);
}
for(i=0; i<5; i++){
pthread_detach(ptid[i]);
pthread_detach(ctid[i]);
}
while(1){
sleep(10);
}
pthread_mutex_destroy(&mutex);
pthread_exit(NULL);
return 0;
}