1 //初始化循环队列 2 void InitQue(PT_QUEUE ptQue) 3 { 4 memset(ptQue, 0, sizeof(*ptQue)); 5 } 6 7 //向循环队列中插入元素 8 void EnterQue(PT_QUEUE ptQue, int dwElem) 9 { 10 if(IsQueFull(ptQue)) 11 { 12 printf("Elem %d cannot enter Queue %p(Full)!\n", dwElem, ptQue); 13 return; 14 } 15 ptQue->aData[ptQue->dwTail]= dwElem; 16 ptQue->dwTail = (ptQue->dwTail + 1) % QUEUE_SIZE; 17 } 18 19 //从循环队列中取出元素 20 int LeaveQue(PT_QUEUE ptQue) 21 { 22 if(IsQueEmpty(ptQue)) 23 { 24 printf("Queue %p is Empty!\n", ptQue); 25 return -1; 26 } 27 int dwElem = ptQue->aData[ptQue->dwHead]; 28 ptQue->dwHead = (ptQue->dwHead + 1) % QUEUE_SIZE; 29 return dwElem; 30 } 31 32 //从队首至队尾依次显示队中元素值 33 void DisplayQue(PT_QUEUE ptQue) 34 { 35 if(IsQueEmpty(ptQue)) 36 { 37 printf("Queue %p is Empty!\n", ptQue); 38 return; 39 } 40 41 printf("Queue Element: "); 42 int dwIdx = ptQue->dwHead; 43 while((dwIdx % QUEUE_SIZE) != ptQue->dwTail) 44 printf("%d ", ptQue->aData[(dwIdx++) % QUEUE_SIZE]); 45 46 printf("\n"); 47 } |
1 //判断循环队列是否为空 2 int IsQueEmpty(PT_QUEUE ptQue) 3 { 4 return ptQue->dwHead == ptQue->dwTail; 5 } 6 7 //判断循环队列是否为满 8 int IsQueFull(PT_QUEUE ptQue) 9 { 10 return (ptQue->dwTail + 1) % QUEUE_SIZE == ptQue->dwHead; 11 } 12 13 //获取循环队列元素数目 14 int QueDataNum(PT_QUEUE ptQue) 15 { 16 return (ptQue->dwTail - ptQue->dwHead + QUEUE_SIZE) % QUEUE_SIZE; 17 } 18 19 //获取循环队列队首位置 20 int GetQueHead(PT_QUEUE ptQue) 21 { 22 return ptQue->dwHead; 23 } 24 //获取循环队列队首元素 25 int GetQueHeadData(PT_QUEUE ptQue) 26 { 27 return ptQue->aData[ptQue->dwHead]; 28 } 29 //获取循环队列队尾位置 30 int GetQueTail(PT_QUEUE ptQue) 31 { 32 return ptQue->dwTail; 33 } |
1 static T_QUEUE gtQueue; 2 void QueueTest(void) 3 { 4 InitQue(>Queue); 5 printf("Enter Queue 1,2,3,4,5...\n"); 6 EnterQue(>Queue, 1); 7 EnterQue(>Queue, 2); 8 EnterQue(>Queue, 3); 9 EnterQue(>Queue, 4); 10 EnterQue(>Queue, 5); 11 printf("Queue Status: Empty(%d), Full(%d)\n", IsQueEmpty(>Queue), IsQueFull(>Queue)); 12 printf("Queue Elem Num: %u\n", QueDataNum(>Queue)); 13 printf("Head: %u(%d)\n", GetQueHead(>Queue), GetQueHeadData(>Queue)); 14 printf("Tail: %u\n", GetQueTail(>Queue)); 15 DisplayQue(>Queue); 16 17 printf("\nLeave Queue...\n"); 18 printf("Leave %d\n", LeaveQue(>Queue)); 19 printf("Leave %d\n", LeaveQue(>Queue)); 20 printf("Leave %d\n", LeaveQue(>Queue)); 21 DisplayQue(>Queue); 22 23 printf("\nEnter Queue 6,7...\n"); 24 EnterQue(>Queue, 6); 25 EnterQue(>Queue, 7); 26 DisplayQue(>Queue); 27 28 printf("\nLeave Queue...\n"); 29 printf("Leave %d\n", LeaveQue(>Queue)); 30 printf("Leave %d\n", LeaveQue(>Queue)); 31 printf("Leave %d\n", LeaveQue(>Queue)); 32 DisplayQue(>Queue); 33 } |
1 Enter Queue 1,2,3,4,5... 2 Elem 5 cannot enter Queue 0x8053f9c(Full)! 3 Queue Status: Empty(0), Full(1) 4 Queue Elem Num: 4 5 Head: 0(1) 6 Tail: 4 7 Queue Element: 1 2 3 4 8 9 Leave Queue... 10 Leave 1 11 Leave 2 12 Leave 3 13 Queue Element: 4 14 15 Enter Queue 6,7... 16 Queue Element: 4 6 7 17 18 Leave Queue... 19 Leave 4 20 Leave 6 21 Leave 7 22 Queue 0x8053f9c is Empty! |
1 int main(void) 2 { 3 InitQue(>Queue); 4 srand(getpid()); //初始化随机函数发生器 5 6 pthread_t aThrd[CONSUMER_NUM+PRODUCER_NUM]; 7 int dwThrdIdx; 8 for(dwThrdIdx = 0; dwThrdIdx < CONSUMER_NUM; dwThrdIdx++) 9 { //创建CONSUMER_NUM个消费者线程,传入(void*)dwThrdIdx作为ConsumerThread的参数 10 pthread_create(&aThrd[dwThrdIdx], NULL, ConsumerThread, (void*)dwThrdIdx); 11 } 12 sleep(2); 13 for(dwThrdIdx = 0; dwThrdIdx < PRODUCER_NUM; dwThrdIdx++) 14 { 15 pthread_create(&aThrd[dwThrdIdx], NULL, ProducerThread, (void*)dwThrdIdx); 16 } 17 while(1); 18 return 0 ; 19 } |
1 void *ProducerThread(void *pvArg) 2 { 3 pthread_detach(pthread_self()); 4 int dwThrdNo = (int)pvArg; 5 while(1) 6 { 7 pthread_mutex_lock(>QueLock); 8 while(IsQueFull(>Queue)) //队列由满变为非满时,生产者线程被唤醒 9 pthread_cond_wait(>PrdCond, >QueLock); 10 11 EnterQue(>Queue, GetQueTail(>Queue)); //将队列元素下标作为元素值入队 12 if(QueDataNum(>Queue) == 1) //当生产者开始产出后,通知(唤醒)消费者线程 13 pthread_cond_broadcast(>CsmCond); 14 printf("[Producer %2u]Current Product Num: %u\n", dwThrdNo, QueDataNum(>Queue)); 15 16 pthread_mutex_unlock(>QueLock); 17 sleep(rand()%DELAY_TIME + 1); 18 } 19 } 队列变满时,生产者线程进入休眠状态。消费者线程取出产品,将队列由满变为非满时,生产者线程再次被唤醒。 消费者线程启动例程ConsumerThread()实现如下: 1 void *ConsumerThread(void *pvArg) 2 { 3 pthread_detach(pthread_self()); 4 int dwThrdNo = (int)pvArg; 5 while(1) 6 { 7 pthread_mutex_lock(>QueLock); 8 while(IsQueEmpty(>Queue)) //队列由空变为非空时,消费者线程将被唤醒 9 pthread_cond_wait(>CsmCond, >QueLock); 10 11 if(GetQueHead(>Queue) != GetQueHeadData(>Queue)) 12 { 13 printf("[Consumer %2u]Product: %d, Expect: %d\n", dwThrdNo, 14 GetQueHead(>Queue), GetQueHeadData(>Queue)); 15 exit(0); 16 } 17 LeaveQue(>Queue); 18 if(QueDataNum(>Queue) == (PRD_NUM-1)) //当队列由满变为非满时,通知(唤醒)生产者线程 19 pthread_cond_broadcast(>PrdCond); 20 printf("[Consumer %2u]Current Product Num: %u\n", dwThrdNo, QueDataNum(>Queue)); 21 22 pthread_mutex_unlock(>QueLock); 23 sleep(rand()%DELAY_TIME + 1); 24 } 25 } |
1 #define QUEUE_SIZE 20 2 volatile unsigned int gdwPrdNum = 0, gdwCsmNum = 0; 3 int gQueue[QUEUE_SIZE] = {0}; 4 5 void *Producer(void *pvArg) { 6 while(1) { 7 while(gdwPrdNum - gdwCsmNum == QUEUE_SIZE) 8 ; //Full 9 10 gQueue[gdwPrdNum % QUEUE_SIZE]++; 11 gdwPrdNum++; 12 } 13 pthread_exit(0); 14 } 15 16 void *Consumer(void *pvArg) { 17 while(1) { 18 while(gdwPrdNum - gdwCsmNum == 0) 19 ; //Empty 20 21 gQueue[gdwCsmNum % QUEUE_SIZE]--; 22 gdwCsmNum++; 23 } 24 pthread_exit(0); 25 } |
原文:http://www.blogjava.net/qileilove/archive/2014/10/30/419269.html