Linux C —— 多線程

爲了防止無良網站的爬蟲抓取文章,特此標識,轉載請註明文章出處。LaplaceDemon/ShiJiaqi。html

http://www.cnblogs.com/shijiaqi1066/p/5769417.htmlnode

 

 

線程基礎

建立線程

pthread_create多線程

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void),  void *restrict arg);

【參數】函數

  • tidp:傳入函數,該函數會把建立的線程指針賦值給該參數。
  • attr:線程屬性。
  • start_rtn:啓動線程的函數指針。
  • arg:運行函數的參數。

【返回值】成功,返回0;出錯,返回-1。oop

 

線程掛起

pthread_join性能

#include <pthread.h>
int pthread_join( pthread_t thread, void **value_ptr);

讓當前線程在等待指定線程執行完後再繼續執行。網站

參數:spa

  • thread:等待退出線程的線程號。
  • value_ptr:退出線程的返回值。

 

線程退出

pthread_exit線程

#include <pthread.h>
void pthread_exit(void *rval_ptr);

退出當前線程。該函數用於線程函數主動退出,而不是讓其餘線程退出。指針

 

獲取當前線程id

pthread_self

#include <pthread.h>
pthread_t pthread_self(void);

獲取當前線程。線程ID由是pthread_t類型表示。

 

判斷線程是否相等

pthread_equal

#include <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2);

檢查兩個pthread是否相等。

在不一樣的系統下,pthread_t的類型是不一樣的,好比在ubuntn下,是unsigned long類型,而在solaris系統中,是unsigned int類型。而在FreeBSD上才用的是結構題指針。 因此不能直接使用==判讀,而應該使用pthread_equal來判斷。

 

 


例:建立線程

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// 線程一
void thread_1(void) {
    int i = 0;
    for(i = 0; i <= 6; i++) {
        printf("This is a pthread_1.\n");
        if(i == 2) {
            pthread_exit(0);
        }
        sleep(1);
    }
}

// 線程二
void thread_2(void) {
    int i;
    for(i = 0; i < 3; i++) {
        printf("This is a pthread_2.\n");
    }
    pthread_exit(0);
}

int main(void) {
    pthread_t id_1, id_2;
    int ret;

    /*建立線程一*/
    ret=pthread_create(&id_1, NULL, (void  *) thread_1, NULL);
    if(ret != 0) {
        printf("Create pthread error!\n");
        return -1;
    }

    /*建立線程二*/
    ret=pthread_create(&id_2, NULL, (void  *) thread_2, NULL);
    if(ret != 0) {
        printf("Create pthread error!\n");
        return -1;
    }

    /*等待線程結束*/
    pthread_join(id_1, NULL);
    pthread_join(id_2, NULL);
    return 0;
}

 

線程執行函數的返回值

  • pthread_exit(void *ret)
  • pthread_join(pthread_t id, void **ret)

函數退出時,由pthread_exit函數退出,並用ret傳出真正的返回值。外部函數若想接受到該參數,使用pthread_join的第二個參數來接收。

 

 

回收線程資源

pthread_detach

#include <pthread.h>
int pthread_detach(pthread_t);

線程分離。

Linux的線程有兩種狀態:

  • joinable
  • unjoinable

默認線程是joinable的,則當線程函數本身返回退出時或pthread_exit時都不會釋放線程所佔用堆棧和線程描述符(總計8K多)。只有對該線程調用了pthread_join以後這些資源纔會被釋放。

線程的unjoinable狀態能夠在pthread_create時指定,也能夠在線程建立後在線程中pthread_detach本身, 確保資源的釋放。如:pthread_detach(pthread_self())。

 

通常的回收線程有兩種方法:

方法一:使用pthread_detach讓線程自動回收資源。

pthread_t tid;
int status = pthread_create(&tid, NULL, ThreadFunc, NULL);
if(status != 0){ perror("pthread_create error");
}
pthread_detach(tid);

 

方法二:使用thread_join讓下一個線程回收當前線程。

 

 


互斥量(鎖)

建立互斥量

靜態初始化互斥量

PTHREAD_MUTEX_INITIALIZER

pthread_mutex_t theMutex;
pthread_mutex_t result = PTHREAD_MUTEX_INITIALIZER;

 

動態初始化互斥量

pthread_mutex_init

#include <pthread.h>
int  pthread_mutex_init(pthread_mutex_t  *restrict_mutex,const pthread_mutextattr_t *restrict attr)

 

銷燬鎖

pthread_mutex_destroy

#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);

使用完後釋放。

 

加鎖

pthread_mutex_lock

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);

 

嘗試加鎖

pthread_mutex_trylock

#include <pthread.h>
int pthread_mutex_trylock( pthread_mutex_t *mutex );

加鎖,可是與pthread_mutex_lock不同的是當鎖已經在使用的時候,返回爲EBUSY,而不是掛起等待。

 

在必定時間內加鎖

pthread_mutex_timedlock

#include <pthread.h>
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout); 

嘗試lock,abs_timeout時間內仍被鎖定,返回ETIMEOUT錯誤。timespec是超時時間,它用秒和納秒來描述時間。

 

解鎖

pthread_mutex_unlock

#include <pthread.h>
pthread_mutex_unlock(pthread_mutex_t *mutex);

釋放鎖。

 

例:兩個線程各自加1。

#include <pthread.h>
#include <stdio.h>

void add_1(void *arg);
pthread_mutex_t mutex;

int main() {
    int i = 10;

    // 聲明線程
    pthread_t thread1,thread2;

    // 初始化鎖
    pthread_mutex_init(&mutex,NULL);

    // 建立線程
    int rc1 = pthread_create(&thread1, NULL, (void *)add_1, &i);
    if(rc1 != 0){
        printf("thread-1 create failed: %d\n",rc1);
    }

    // 建立線程
    int rc2 = pthread_create(&thread2, NULL, (void *)add_1, &i);
    if(rc2 != 0){
        printf("thread-2 create failed: %d\n",rc1);
    }

    // 等待線程
    pthread_join(thread1,NULL);
    pthread_join(thread2,NULL);

    printf("i = %d",i);   // 打印輸出 i = 210

    return 0;
}

// 線程運行函數
void add_1(void *arg){
    int *i = (int *)arg;
    for(int n=0;n<100;n++){
        pthread_mutex_lock(&mutex);
        (*i)++;
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(NULL);
}

 


 

讀寫互斥量(讀寫鎖)

 待寫

 


條件鎖

靜態建立

PTHREAD_COND_INITIALIZER

#include <pthread.h>
pthread_cond_t my_condition = PTHREAD_COND_INITIALIZER;

 

動態建立

pthread_cond_init

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

 

銷燬

pthread_cond_destroy

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

 

等待

pthread_cond_wait

#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

 

觸發

pthread_cond_signal

#include <pthread.h>
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);

 


例:生產者消費者

main.c

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

#define BLOCK_POOL_SIZE 10

void producer(void *arg);
void customer(void *arg);

int main() {
    int pthread_ret;
    pthread_t producer_thread_0,producer_thread_1,customer_thread;
    List *plist = block_queue_create(BLOCK_POOL_SIZE);

    pthread_ret = pthread_create(&producer_thread_0,NULL,(void *)producer,plist);
    if(pthread_ret!=0){
        puts("生產者線程建立失敗");
        return EXIT_FAILURE;
    }

    pthread_ret = pthread_create(&producer_thread_1,NULL,(void *)producer,plist);
    if(pthread_ret!=0){
        puts("生產者線程建立失敗");
        return EXIT_FAILURE;
    }

    pthread_ret = pthread_create(&customer_thread,NULL,(void *)customer,plist);
    if(pthread_ret!=0){
        puts("消費者線程建立失敗");
        return EXIT_FAILURE;
    }

    // 主線程等待.
    pthread_join(producer_thread_0,NULL);
    pthread_join(producer_thread_1,NULL);
    pthread_join(customer_thread,NULL);

    block_queue_destroy(plist);
    return EXIT_SUCCESS;
}

void producer(void *arg){
    List *plist = (List *)arg;
    for (int i = 0; i < 40; i++) {
        block_queue_push(plist,i);
        printf("生產數據:%d\n",i);
    }

    printf("---- 生產結束 ----\n");
    pthread_exit(NULL);
}

void customer(void *arg){
    int data;
    List *plist = (List *)arg;
    for (int i = 0; i < 80; i++) {
        block_queue_pop(plist,&data);
        printf("消費數據:%d\n",data);
    }

    printf("---- 消費結束 ----\n");
    pthread_exit(NULL);
}

 

block_queue.h

//
// Created by shijiaqi on 16/11/22.
//
#include <pthread.h>

typedef struct list_node{
    int data;
    struct node *next_node;
} ListNode;

typedef struct list{
    ListNode *firstNode;
    int size;
    int full_size;
    pthread_mutex_t mutex;
    pthread_cond_t cond_for_producer;
    pthread_cond_t cond_for_customer;
} List;

List * block_queue_create(int full_size);

void block_queue_destroy(List *plist);

void block_queue_push(List *plist,int data);

int block_queue_pop(List *plist,int *p_data);

 

block_queue.c

//
// Created by shijiaqi on 16/11/22.
//
#include "block_queue.h"
#include <stdlib.h>
#include <stdio.h>

List * block_queue_create(int full_size){
    // 分配內存
    List *plist = malloc(sizeof(List));
    plist->full_size = full_size;
    plist->size = 0;
    plist->firstNode = NULL;

    // 初始化鎖與條件等待.
    pthread_mutex_init(&(plist->mutex),NULL);
    pthread_cond_init(&(plist->cond_for_customer),NULL);
    pthread_cond_init(&(plist->cond_for_producer),NULL);

    return plist;
}

void block_queue_destroy(List *plist){
    int data = 0;
    int ret = 0;

    // 銷燬全部數據。
    while(ret==0){
        if(plist->size > 0) {
            ret = block_queue_pop(plist, &data);
        }else{
            break ;
        }
    }

    // 銷燬鎖與條件等待
    pthread_cond_destroy(&(plist->cond_for_producer));
    pthread_cond_destroy(&(plist->cond_for_customer));
    pthread_mutex_destroy(&(plist->mutex));

    // 釋放內存
    free(plist);
}

void block_queue_push(List *plist,int data) {
    // lock
    pthread_mutex_lock(&(plist->mutex));

    while(plist->size>=plist->full_size){
        printf("隊列已滿,生產者阻塞。目前倉儲數量:%d\n",plist->size);
        pthread_cond_wait(&(plist->cond_for_producer),&(plist->mutex));
    }

    ListNode *curNode = plist->firstNode;
    if(curNode == NULL) {
        ListNode *new_node = malloc(sizeof(ListNode));
        new_node->next_node = NULL;
        new_node->data = data;
        plist->firstNode = new_node;
        plist->size++;

        printf("隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:%d\n",plist->size);
        pthread_cond_signal(&(plist->cond_for_customer));

        // unlock
        pthread_mutex_unlock(&(plist->mutex));
        return ;
    }

    ListNode *lastNode = curNode;
    curNode = (ListNode *)curNode->next_node;
    for(;;){
        if(curNode==NULL) {
            curNode = malloc(sizeof(ListNode));
            curNode->next_node = NULL;
            curNode->data = data;
            lastNode->next_node = (struct node *)curNode;
            plist->size++;

            printf("隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:%d\n",plist->size);
            pthread_cond_signal(&(plist->cond_for_customer));

            // unlock
            pthread_mutex_unlock(&(plist->mutex));
            return ;
        }
        lastNode = curNode;
        curNode = (ListNode *)curNode->next_node;
    }
}

int block_queue_pop(List *plist,int *p_data) {
    // lock
    pthread_mutex_lock(&(plist->mutex));
    while(plist->size <= 0){
        printf("隊列已空,消費者阻塞。目前倉儲數量:%d\n",plist->size);
        pthread_cond_wait(&(plist->cond_for_customer),&(plist->mutex));
    }

    ListNode *curNode = plist->firstNode;
    if(curNode == NULL){
        printf("隊列爲空,通知阻塞的生產者。目前倉儲數量:%d\n",plist->size);
        pthread_cond_signal(&(plist->cond_for_producer));
        // unlock
        pthread_mutex_unlock(&(plist->mutex));
        return 1;  // no data
    } else {
        *p_data = curNode->data;
        plist->firstNode = (ListNode *)curNode->next_node;
        free(curNode);
        plist->size--;

        printf("隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:%d\n",plist->size);
        pthread_cond_signal(&(plist->cond_for_producer));

        // unlock
        pthread_mutex_unlock(&(plist->mutex));
        return 0;
    }
}

打印輸出:

隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:1
生產數據:0
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:2
生產數據:0
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:1
消費數據:0
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:2
生產數據:1
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:3
生產數據:1
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:2
消費數據:0
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:3
生產數據:2
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:4
生產數據:2
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:3
消費數據:1
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:4
生產數據:3
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:5
生產數據:3
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:4
消費數據:1
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:5
生產數據:4
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:6
生產數據:4
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:5
消費數據:2
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:6
生產數據:5
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:7
生產數據:5
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:6
消費數據:2
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:7
生產數據:6
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:8
生產數據:6
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:7
消費數據:3
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:8
生產數據:7
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:9
生產數據:7
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:8
消費數據:3
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:9
生產數據:8
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:8
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:4
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:9
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:4
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:5
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:9
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:5
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:6
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:11
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:6
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:12
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:7
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:11
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:7
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:12
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:8
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:13
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:8
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:14
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:9
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:13
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:10
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:14
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:9
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:15
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:10
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:16
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:11
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:15
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:12
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:16
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:11
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:17
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:12
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:18
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:13
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:17
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:14
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:18
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:13
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:19
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:14
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:20
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:15
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:19
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:16
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:20
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:15
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:21
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:16
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:22
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:17
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:23
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:18
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:24
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:17
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:21
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:18
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:22
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:19
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:25
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:20
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:26
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:19
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:23
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:20
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:24
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:21
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:27
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:22
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:28
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:23
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:25
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:24
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:26
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:21
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:29
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:22
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:30
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:25
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:27
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:26
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:28
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:23
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:31
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:24
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:32
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:27
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:29
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:28
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:30
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:25
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:33
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:26
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:34
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:29
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:31
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:30
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:32
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:27
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:35
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:28
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:36
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:31
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:33
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:32
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:34
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:29
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:35
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:30
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:36
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:33
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:37
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:34
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:38
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:31
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:37
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:32
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:38
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:35
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:10
生產數據:39
---- 生產結束 ----
隊列已滿,生產者阻塞。目前倉儲數量:10
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:9
消費數據:36
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:8
消費數據:33
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:7
消費數據:34
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:6
消費數據:35
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:5
消費數據:36
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:4
消費數據:37
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:3
消費數據:38
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:2
消費數據:37
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:1
消費數據:38
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:0
消費數據:39
隊列剛纔生產一條數據,通知阻塞的消費者。目前倉儲數量:1
生產數據:39
---- 生產結束 ----
隊列被消費了一條數據,通知阻塞的生產者。目前倉儲數量:0
消費數據:39
---- 消費結束 ----

 

 


 

例:實現線程的sleep函數。Linux是沒法直接使線程sleep的,因此須要使用 pthread_cond_timedwait() 函數實現線程的sleep函數。

如下實現性能可能有問題,由於須要重複初始化/銷燬互斥量與等待條件量。這裏主要是要給出pthread_cond_timedwait使用方法與簡單實現sleep函數。

main.c

#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include "pthread_sleep.h"

void test_loop();

int main() {
    pthread_t thread;
    pthread_create(&thread,NULL,(void *)test_loop,NULL);
    pthread_join(thread,NULL);
    return 0;
}

void test_loop() {
    time_t now;

    for(;;){
        pthread_sleep(1);
        time(&now);
        printf("%s",asctime(gmtime(&now)));
    }
}

 

 

pthread_sleep.h

#ifndef C_POINTER_PTHREAD_SLEEP_H
#define C_POINTER_PTHREAD_SLEEP_H

#endif //C_POINTER_PTHREAD_SLEEP_H

unsigned int pthread_sleep(unsigned int seconds);

 

 

pthread_sleep.c

#include <pthread.h>
#include <sys/time.h>
#include "pthread_sleep.h"

unsigned int pthread_sleep(unsigned int seconds) {
    pthread_cond_t cond;
    pthread_mutex_t mutex;

    // 建立鎖
    pthread_cond_init(&cond,NULL);
    pthread_mutex_init(&mutex,NULL);

    // 時間計算。此處計算的是,等待的截止時間。即當前時刻到達這個時間點,線程就再也不被阻塞。
    struct timeval now;
    gettimeofday(&now, NULL);
    struct timespec sleep_time = {now.tv_sec + seconds,0};

    // 加鎖
    pthread_mutex_lock(&mutex);

    // 等待。等到到指定時間,繼續執行。
    pthread_cond_timedwait(&cond,&mutex,&sleep_time);

    // 解鎖
    pthread_mutex_unlock(&mutex);

    // 銷燬
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);

    return 0;
}

 

 

 

 

 

 

 

爲了防止無良網站的爬蟲抓取文章,特此標識,轉載請註明文章出處。LaplaceDemon/ShiJiaqi。

http://www.cnblogs.com/shijiaqi1066/p/5769417.html

相關文章
相關標籤/搜索