程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> linux下生產者與消費者C實現

linux下生產者與消費者C實現

編輯:關於C語言

最近做畢設涉及到了生產者與消費者模型,這個東東只在操作系統課程上有點印象,於是花了點時間看了下《unix環境高級編程 》的線程部分,在此記錄一下。

1.多線程的概念就不多說了,pthread.h頭文件中包含的幾個基本概念及函數:

pthread_t————線程ID數據類型,線程ID只在它所屬的進程環境中有效;

int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, func(void), arg)————創建新的線程,若成功返回0設置tidp指向的單元為新線程的線程IDattr用來設置線程屬性,一般默認為NULLfunc為新線程調用的入口函數,該函數只能有一個無類型指針參數arg,若要向函數傳遞多個參數,需要將所有參數放到一個結構中,再把結構地址傳遞給arg

pthread_t pthread_self(void)————獲取自身線程ID

void pthread_exit(void *rval_ptr)———終止本線程,用rval_ptr指向的值作為退出碼

int pthread_join(pthread_t thread, void **rval_ptr)————調用該函數的線程將阻塞,直到thread線程調用pthread_exit、從啟動例程返回或被取消,rval_ptr將包含返回碼

int pthread_cancel(pthread_t tid)————該函數用來請求取消統一進程中的其他線程

2.線程同步————互斥量、讀寫鎖,條件變量

讀寫鎖即共享——獨占鎖,適合於讀的次數遠大於寫的情況,比較好理解,就不多說了。

條件變量由互斥量保護,線程在改變條件狀態之前必須先鎖定互斥量。

生產者與消費者模型用到了互斥量和條件變量,對隊列進行讀寫,下面直接上代碼:

隊列操作(數據結構的內容),采用鏈式結構:

#include <stdio.h>   
#include <stdlib.h>   
#include <stdbool.h>   
#include <string.h>   
#include <time.h>   
#include <unistd.h>   
#include <pthread.h>   
       
#define MAXLENGTH 10    //the maxlength of queue   
       
typedef char * datatype;   
typedef struct node {    //define node   
    datatype name;   
    struct node *next;   
} node;   
typedef struct queue {    //define queue   
    node *front, *rear;   
    int len;   
} queue;   
       
void queue_init(queue *q)   
{   
    q->front = q->rear = NULL;   
    q->len = 0;   
}   
       
void  queue_put(queue *q, datatype new_name)  //入隊   
{   
    node *mynode = (node *)malloc(sizeof(node));   
    mynode->name = new_name;   
    mynode->next = NULL;   
    if (q->rear)   
        q->rear->next = mynode;   
    q->rear = mynode;   
    if (q->front == NULL)   
        q->front = mynode;   
    q->len++;   
}   
       
datatype queue_get(queue *q)   //出隊   
{   
    node *mynode;   
    datatype myname;   
    if (q->front != NULL)   
        mynode = q->front;   
    myname = mynode->name;   
    q->front = q->front->next;   
    q->len--;   
    free(mynode);   
    return myname;   
}   
       
void queue_print(queue *q)  //print queue   
{   
    node *tmp = q->front;   
    while(tmp != NULL)   
    {   
        printf("%s ", tmp->name);   
        tmp = tmp->next;   
    }   
    printf("n");   
}

生產者與消費者函數:

/*define mutex and condtion var*/   
pthread_cond_t q_not_full = PTHREAD_COND_INITIALIZER;   
pthread_cond_t q_not_empty = PTHREAD_COND_INITIALIZER;   
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;   
       
/*   
 * producer function   
 */   
void producer(void *q)   
{   
//    printf("start porducer:n");   
    queue *qt = q;    //傳入的隊列   
    while(1)   
    {   
        pthread_mutex_lock(&qlock);   
//        printf("producer has locked the qlockn");   
        if(qt->len >= MAXLENGTH)    //queue is full   
        {   
//            printf("producer is going to waitingn");   
            pthread_cond_wait(&q_not_full, &qlock);   
        }   
        queue_put(qt, "* ");   
//        printf("after producer: queue's length is %dn", qt->len);   
        pthread_mutex_unlock(&qlock);   
        pthread_cond_signal(&q_not_empty);   
       
//        printf("producer has unlocked the qlockn");   
//        sleep(1);   
    }   
}   
       
/*   
 * consumer function   
 */
void consumer(void *q)   
{   
//    printf("start consumer:n");   
    queue *qt = q;   
    while(1)   
    {   
        pthread_mutex_lock(&qlock);   
//        printf("consumer has locked the qlockn");   
        if(qt->len <= 0)    //queue is empty   
        {   
//            printf("consumer is going to waitingn");   
            pthread_cond_wait(&q_not_empty, &qlock);   
        }   
        datatype back_name = queue_get(qt);   
//        printf("after consumer, queue's length is %dn", qt->len);   
        pthread_mutex_unlock(&qlock);   
        pthread_cond_signal(&q_not_full);   
//        now process the back_name   
//        printf("cousumer has unlocked the qlockn");   
//        sleep(1);   
    }   
}

主函數(測試):

//gcc編譯時加上-lpthread   
int main() {   
    pthread_t tid1, tid2;   
    queue *q=(queue *)malloc(sizeof(queue));   
    queue_init(q);   
//    queue_put(q, "one");   
//    queue_put(q, "two");   
//    queue_put(q, "three");   
//    queue_get(q);   
//    printf("len = %dn", q->len);   
//    queue_print(q);   
       
    long stime = clock();   
    long etime = clock();   
       
    pthread_create(&tid1, NULL, (void *)producer, (void *)q);   
    pthread_create(&tid2, NULL, (void *)consumer, (void *)q);   
       
    while((float)(etime-stime)/CLOCKS_PER_SEC < 0.00001)   
    {   
        etime = clock();   
    }   
    return 0;   
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved