生产者消费者问题的条件变量实现
condition.h
#ifndef CONDITION_H #define CONDITION_H #include <pthread.h> #define N 10 typedef struct job { struct job *j_next; struct job *j_prev; // pthread_t tid; } Job; typedef struct queue{ Job *head; Job *tail; pthread_mutex_t qlock; pthread_cond_t notFull; pthread_cond_t notEmpty; // pthread_t tid; int size; } Queue; int Arg_int(Queue *argp); void* Append(void *argp); void* Remove(void * argp); int my_pthread_create(pthread_t *tidp, const pthread_attr_t * attr, void *(*start_rnt)(void*), void *arg); void print(const Queue* p); #endif
condition.c
#include <string.h>
#include <stdio.h>
#include "condition.h"
#include <stdlib.h>
int Arg_int(Queue* qp){
int elock,econd1,econd2;
if ((qp = (Queue*)malloc(sizeof(Queue)) )== NULL)
exit(1);
qp->head = NULL;
qp->tail = NULL;
qp->size = 0;
// print(qp);
elock = pthread_mutex_init(&qp->qlock, NULL);
if (elock != 0){
printf(" mutex qlock initiate failed: %s\n",strerror(elock));
return elock;
}
econd1 = pthread_cond_init(&qp->notFull, NULL);
if (econd1 != 0){
printf(" mutex qlock initiate failed: %s\n",strerror(econd1));
return econd1;
}
econd2 = pthread_cond_init(&qp->notEmpty, NULL);
if (econd2 != 0){
printf(" mutex qlock initiate failed: %s\n",strerror(econd2));
return econd2;
}
return 0;
} //TODO
void* Append(void *arg){
Queue* qp = (Queue*)arg;
while(1){
pthread_mutex_lock(&(qp->qlock));
while(qp->size == N){ //while????
printf("Apprnd Thread %x is susppend, size: %d.\n",(unsigned)pthread_self(), qp->size);
pthread_cond_wait(&qp->notFull, &qp->qlock);
}
Job* jp = malloc(sizeof(Job));
jp->j_next = NULL;
jp->j_prev = qp->tail;
if(qp->tail != NULL)
qp->tail->j_next = jp;
else
qp->head = jp;
qp->tail = jp;
qp->size += 1;
// printf("%p\n",jp);
// print(qp);
printf("Append Pthread %x Runing, size: %d.\n",(unsigned)pthread_self(), qp->size);
int err;
if ((err = pthread_cond_signal(&qp->notEmpty)) != 0)
printf("Append Thread signal Remove Thread Failed: %s.\n",strerror(err) );
else
printf("Append Thread signal a Remove Thread on notEmpty, size: %d.\n", qp->size);
pthread_mutex_unlock(&qp->qlock);
}
return ((void*)1);
}
void* Remove(void * arg){
Queue* qp = (Queue*)arg;
while(1){
pthread_mutex_lock(&qp->qlock);
while(qp->size == 0){
printf("Remove Thread %x is susppend, size: %d.\n",(unsigned)pthread_self(), qp->size);
pthread_cond_wait(&qp->notEmpty,&qp->qlock);
}
Job* tp = qp->head;
qp->head = tp->j_next;
if (qp->head != NULL)
qp->head->j_prev = NULL;
else
qp->tail = NULL;
// if (qp->tail != tp)
// tp->j_next->j_prev = tp->j_prev;
// else
// qp->tail = NULL;
free(tp);
qp->size -= 1;
// print(qp);
printf("Remove Pthread %x Runing, size: %d.\n",(unsigned)pthread_self(), qp->size);
int err;
if ((err = pthread_cond_signal(&qp->notFull)) != 0)
printf("Remove Thread signal Append Thread Failed: %s.\n",strerror(err) );
else
printf("Remove Thread signal a Append Thread on notFull, size: %d.\n", qp->size);
pthread_mutex_unlock(&qp->qlock);
}
return((void*)1);
}
int my_pthread_create(pthread_t *tidp, const pthread_attr_t * attr, void *(*start_rnt)(void*), void *arg){
int result = pthread_create(tidp, attr,start_rnt, arg);
if (result != 0){
printf("thread(0x%x) call pthread_creat fialed: %s\n",( unsigned )pthread_self(), strerror(result));
}
else{
printf("thread(0x%x) carated new thread: 0x%x(%d)\n",( unsigned )pthread_self(), (unsigned)*tidp,(unsigned)*tidp);
}
return result;
}
void print(const Queue* p){
Job *qp = p->head;
while(qp != p->tail){
printf("%p: %p --> ", p, qp);
qp = qp->j_next;
}
printf("%p: %p --> ", p, qp);
printf("NULL\n");
}
- main.c
#include <string.h>
#include <stdio.h>
#include "condition.h"
#include <stdlib.h>
int main(){
Queue* qp = (Queue*)malloc(sizeof(Queue));
int i;
pthread_t tid[20];
Arg_int(qp);
for(i = 0; i < 10; ++i){
my_pthread_create(tid + i, NULL, Append, qp);
}
for(i = 10; i < 15; ++i){
my_pthread_create(tid + i, NULL, Remove, qp);
}
for(i = 0; i < 15 ;++i){
pthread_join(*(tid +i), NULL);
printf("Thread %x is joined.\n",(unsigned)tid[i]);
}
// sleep(2);
return 0;
}