1. 程式人生 > >linux c語言實現佇列及用於生產者消費者模型

linux c語言實現佇列及用於生產者消費者模型

c語言沒有佇列的資料結構,需要自己實現
//myqueue.h
#ifndef __MYQUEUE_H__
#define __MYQUEUE_H__

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define DBG(...) printf("myqueue %s, %d: ",__FUNCTION__,__LINE__);printf(__VA_ARGS__)

#define MAXCNTBUF 1024*12
typedef struct Point2D
{
	int len;
	unsigned char buf[MAXCNTBUF ];
}ElemType;   

typedef struct
{
	ElemType **rear;   
	ElemType *front;   
	int len;           
	int size;           

	pthread_mutex_t locker;    
	pthread_cond_t notEmpty;
	pthread_cond_t notFull;
}ArrQueue;     



ArrQueue *CreateQueue( int nLen)   ;     
void DestroyQueue( ArrQueue *pQueue );     
void ClearQueue( ArrQueue *pQueue );   
int GetLength( ArrQueue *pQueue );         
int GetSize( ArrQueue *pQueue );     
int IsEmpty( ArrQueue *pQueue );         
int GetHead( ArrQueue *pQueue, ElemType **pe );    
int EnQueue( ArrQueue *pQueue, ElemType *pe );       
int DeQueue( ArrQueue *pQueue, ElemType **pe ); 
void ForEachQueue( ArrQueue *pQueue, void (*func)(ElemType *pe) );  
#endif



//muqueue.c
#include "myqueue.h"
ArrQueue *CreateQueue( int nLen )
{
    ArrQueue *pQueue = (ArrQueue *)malloc( sizeof(ArrQueue) );
    pQueue->rear = (ElemType **)calloc( nLen, sizeof(ElemType **) );
    pQueue->front = pQueue->rear[0];
    pQueue->len = 0;
    pQueue->size = nLen;

	pthread_mutex_init(&pQueue->locker,NULL);
	pthread_cond_init(&pQueue->notEmpty,NULL);
	pthread_cond_init(&pQueue->notFull,NULL);

    return pQueue;
}

void DestroyQueue( ArrQueue *pQueue )
{
    free( pQueue->rear );
    free( pQueue );

	pthread_mutex_destroy(&pQueue->locker);
	pthread_cond_destroy(&pQueue->notEmpty);
	pthread_cond_destroy(&pQueue->notFull);

    pQueue = NULL;
}

void ClearQueue( ArrQueue *pQueue )
{
    pQueue->front = pQueue->rear[0];

    pQueue->len = 0;
}


int GetLength( ArrQueue *pQueue )
{
    return pQueue->len;
}


int GetSize( ArrQueue *pQueue )
{
    return pQueue->size;
}

int IsEmpty( ArrQueue *pQueue )
{
    return pQueue->len == 0 ? TRUE : FALSE;
}

int IsFull( ArrQueue *pQueue )
{
DBG("pQueue->len=%d,pQueue->size=%d\n",pQueue->len,pQueue->size);
    return pQueue->len == pQueue->size? TRUE : FALSE;
}

int GetHead( ArrQueue *pQueue, ElemType **pe )
{
    if( pQueue->len == 0 )
    {
        *pe = NULL;
        return -1;
    }

    *pe = pQueue->rear[pQueue->len-1];

    return pQueue->len-1;
}

int EnQueue( ArrQueue *pQueue, ElemType *pe )
{
    pthread_mutex_lock(&pQueue->locker);

	while (IsFull(pQueue))
	{
		DBG("\n");
		pthread_cond_wait(&pQueue->notFull, &pQueue->locker);
	} 

    int i = 0;
    for( i = pQueue->len; i > 0; --i )
    {
        pQueue->rear[i] = pQueue->rear[i-1];
    }
    pQueue->rear[0] = pe;
    pQueue->front = pQueue->rear[pQueue->len];

     ++pQueue->len;

	pthread_cond_signal(&pQueue->notEmpty);
	pthread_mutex_unlock(&pQueue->locker);

}

int DeQueue( ArrQueue *pQueue, ElemType **pe )
{

	pthread_mutex_lock(&pQueue->locker);
	while (IsEmpty(pQueue))
	{
		pthread_cond_wait(&pQueue->notEmpty, &pQueue->locker);
	}


	if( pQueue->len == 0 )
	{
		*pe = NULL;
		return -1;
	}

	*pe = pQueue->front;

DBG("len= %d,%x \n",(*pe)->len,(*pe)->len);

	--pQueue->len;
	pQueue->front = pQueue->rear[pQueue->len-1];

	pthread_cond_signal(&pQueue->notFull); 
	pthread_mutex_unlock(&pQueue->locker);

    return pQueue->len;
}


void ForEachQueue( ArrQueue *pQueue, void (*func)(ElemType *pe) )
{
    int i = 0;
    for( i = 0; i < pQueue->len; ++i )
    {
        func( pQueue->rear[i] );
    }
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include "myqueue.h"
<span style="font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px; background-color: rgb(248, 248, 248);">ArrQueue m_pque;</span>
void getqueue()
{
	ElemType *elememt;

	while(1)
		{
		usleep(1000*20);
			DeQueue( m_pque, &elememt );

			if(elememt==NULL)
			{
				printf("fdafsaf");
				DBG("d ReadOneNaluFromQueue elememt==NULL \n");
			}

				

			int jj=0;
			DBG("elememt.len=%d ,0x%x:",elememt->len,elememt->len);
			for(jj=0;jj<10;jj++)
				printf("%x ",elememt->buf[jj]);
		    	printf("\n");
			free( elememt);
		}

}


void sendtoqueue()
{

    HI_S32 i;
	int j=0;
	ElemType *elememt=NULL;
	static int ii=0;
	while(1)
	{


system("free");
				elememt=(ElemType *)malloc(sizeof(ElemType)); 
				
				if(elememt==NULL)
				{
					printf("0 malloc(sizeof(ElemType))");
					exit(0);
				}
				memset(elememt,0,sizeof(ElemType));
				elememt->buf[0]=ii;
				elememt->len=ii++;
				
				int jj=0;
				DBG("elememt.len=%d ,0x%x:",elememt->len,elememt->len);
				for(jj=0;jj<10;jj++)
					printf("%x ",elememt->buf[jj]);
				printf("\n");
				
				EnQueue( m_pque, elememt );


	    } 

}

/******************************************************************************
* function    : main()
* Description : video venc sample
******************************************************************************/
int main(int argc, char *argv[])
{

#if 0

	m_pque = CreateQueue( 20 );
#if 1
	pthread_t td;
	int ret =pthread_create(&td,NULL,getqueue,NULL);
	if(ret!=0){
		printf("create thread err\n");
	}

	pthread_t td2;
	ret =pthread_create(&td2,NULL,sendtoqueue,NULL);
	if(ret!=0){
		printf("create thread err\n");
	}

 #endif


while(1)
	sleep(1);



多執行緒與cpu時間片
top中的idle是通過idle thread來計算了。簡單的說,當時鍾中斷到來時,kernel會判斷當前執行的是否是idle thread並維護一個統計值。在idle thread中的次數越多,說明系統越空閒,反之系統繁忙。