这里的代码围绕一个生产者和一个消费者来分析,生产者生产一个产品,消费者才能使用一个产品,消费者和生产者是同步关系。
一:不加同步互斥锁
pthre#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>typedef struct _Node{
struct _Node* next;
int data;
}node_t,*node_p,**node_pp;//创建结构体
node_p alloc_node(int x){ //为节点开辟空间
node_p p=(node_p)malloc(sizeof(node_t));
if(!p){
perror("malloc");
exit(1);
}
p->data=x;
p->next=NULL;
return p;
}
void init_list(node_pp h){ //初始化链表
if(h==NULL){
return;
}
*h=alloc_node(0);
}
void list_push(node_p h,int x){ //插入节点(生产者生产产品放入链表中)
node_p p=alloc_node(x);
p->next=h->next;
h->next=p;
}
int is_empty(node_p head){//判断链表是否为空
return head->next==NULL?1:0;
}
void list_pop(node_p head,int* x){//删除节点(在这里是消费者消费产品)
if(!is_empty(head)){
node_p p=head->next;
*x=p->data;
head->next=p->next;
free(p);
}
}
void list_destroy(node_p h){//销毁链表
int x;
while(!is_empty(h)){
list_pop(h,&x) ;
}
free(h);
}
void show_list(node_p h){//打印链表
if(!is_empty(h)){
node_p p=h->next;
while(p){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
}
void* consumer(void* arg){//消费者代码
node_p head=(node_p)arg;
while(1){
int data;
list_pop(head,&data);
printf("consumer done! data is:%d\n",data);
sleep(1);
}
}
void* product(void* arg){//生产者代码
while(1){
node_p head=(node_p)arg;
if(is_empty(head)){
int data;
data=rand()%100+1;
list_push(head,data);
printf("product done! data is:%d\n",data);
}else{
printf("product waiting!\n");
}
sleep(2);
}
}
int main(){
node_p head;
init_list(&head);
pthread_create(&c,NULL,consumer,(void*)head);
pthread_create(&p,NULL,product,(void*)head);
pthread_join(c,NULL);
pthread_join(p,NULL);
list_destroy(head);
}
结果:
由结果可以分析两种情况:
1>消费者消费的快,而生产者慢,若不加同步互锁,消费者则反复消费唯一的一个产品。
2>消费者慢,生产者快,若不加同步互斥锁,节点会越来越多,消费者取得永远都是最近生产的一个产品。
二:添加同步互斥锁
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
pthread_mutex_t lock;
pthread_cond_t cond;
typedef struct _Node{
struct _Node* next;
int data;
}node_t,*node_p,**node_pp;
node_p alloc_node(int x){
node_p p=(node_p)malloc(sizeof(node_t));
if(!p){
perror("malloc");
exit(1);
}
p->data=x;
p->next=NULL;
return p;
}
void init_list(node_pp h){
if(h==NULL){
return;
}
*h=alloc_node(0);
}
void list_push(node_p h,int x){
node_p p=alloc_node(x);
p->next=h->next;
h->next=p;
}
int is_empty(node_p head){
return head->next==NULL?1:0;
}
void list_pop(node_p head,int* x){
if(!is_empty(head)){
node_p p=head->next;
*x=p->data;
head->next=p->next;
free(p);
}
}
void list_destroy(node_p h){
int x;
while(!is_empty(h)){
list_pop(h,&x) ;
}
free(h);
}
void show_list(node_p h){
if(!is_empty(h)){
node_p p=h->next;
while(p){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
}
void* consumer(void* arg){
node_p head=(node_p)arg;
while(1){
pthread_mutex_lock(&lock);
if(!is_empty(head)){
int data;
list_pop(head,&data);
printf("consumer done! data is:%d\n",data);
}else{
printf("consumer waiting!\n");
pthread_cond_wait(&cond,&lock);
}
pthread_mutex_unlock(&lock);
sleep(3);
}
}
void* product(void* arg){
while(1){
node_p head=(node_p)arg;
if(is_empty(head)){//通过判断来避免消费者慢生产者快的问题
int data;
data=rand()%100+1;
pthread_mutex_lock(&lock);
list_push(head,data);
pthread_cond_signal(&cond);
printf("product done! data is:%d\n",data);
pthread_mutex_unlock(&lock);
}else{
printf("product waiting!\n");
}
sleep(1);
}
}
int main(){
node_p head;
init_list(&head);
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&cond,NULL);
pthread_t c,p;
pthread_create(&c,NULL,consumer,(void*)head);
pthread_create(&p,NULL,product,(void*)head);
pthread_join(c,NULL);
pthread_join(p,NULL);
list_destroy(head);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
}
结果: