1. 程式人生 > >黑馬《linux系統程式設計》學習筆記(從86到90)

黑馬《linux系統程式設計》學習筆記(從86到90)

八十六. 讀寫鎖練習——程式碼

問題

相應解決的程式碼:

rwlock.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>

// 全域性變數
int number;
pthread_rwlock_t rwlock;

void* write_func(void* arg)
{
    while(1)
    {
		//加寫鎖
        pthread_rwlock_wrlock(&rwlock);
        number++;
        printf("+++ write number: %d\n", number);
		//解鎖
        pthread_rwlock_unlock(&rwlock);
		usleep(1000);
    }
    return NULL;
}

void* read_func(void* arg)
{
    while(1)
    {
		
        pthread_rwlock_rdlock(&rwlock);
        printf("--- read number: %d\n", number);
        pthread_rwlock_unlock(&rwlock);
        usleep(500);
    }
    return NULL;
}

int main(int argc, const char* argv[])
{
    pthread_t thid[8];

    pthread_rwlock_init(&rwlock, NULL);

    // 建立3個寫執行緒
    for(int i=0; i<3; ++i)
    {
        pthread_create(&thid[i], NULL, write_func, NULL);
    }
	//建立5個讀執行緒
    for(int i=3; i<8; ++i)
    {
        pthread_create(&thid[i], NULL, read_func, NULL);
    }

    // 回收子執行緒的pcb
    for(int i=0; i<8; ++i)
    {
        pthread_join(thid[i], NULL);
    }
	
	//釋放讀寫鎖資源
    pthread_rwlock_destroy(&rwlock);

    return 0;
}

八十七. 條件變數的使用思路

八十八. 條件變數相關函式介紹

 

這裡pthread_cond_wait除了阻塞執行緒,還會將已經上鎖的mutex解鎖

八十九. 生產者和消費者模型程式碼實現

condition.c的程式碼

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>

// 節點結構
typedef struct node
{
    int data;
    struct node* next;
}Node;

// 永遠指向連結串列頭部的指標
Node* head = NULL;

// 執行緒同步 - 互斥鎖
pthread_mutex_t mutex;
// 阻塞執行緒 - 條件變數型別的變數
pthread_cond_t cond;

// 生產者
void* producer(void* arg)
{
   while(1)
    {
        // 建立一個連結串列的節點
        Node* pnew = (Node*)malloc(sizeof(Node));
        // 節點的初始化
        pnew->data = rand() % 1000; // 0-999

        // 使用互斥鎖保護共享資料
        pthread_mutex_lock(&mutex);
        // 指標域
        pnew->next = head;
        head = pnew;
        printf("====== produce: %lu, %d\n", pthread_self(), pnew->data);
        pthread_mutex_unlock(&mutex);

        // 通知阻塞的消費者執行緒,解除阻塞
        pthread_cond_signal(&cond);

        sleep(rand() % 3);
    }
    return NULL;
}

void* customer(void* arg)
{
    while(1)
    {
        pthread_mutex_lock(&mutex);
        // 判斷連結串列是否為空
        if(head == NULL)
        {
            // 執行緒阻塞
            // 該函式會對互斥鎖解鎖
            pthread_cond_wait(&cond, &mutex);
            // 解除阻塞之後,對互斥鎖做加鎖操作
        }
        // 連結串列不為空 - 刪掉一個節點 - 刪除頭結點
        Node* pdel = head;
        head = head->next;
        printf("------ customer: %lu, %d\n", pthread_self(), pdel->data);
        free(pdel);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main(int argc, const char* argv[])
{
    pthread_t p1, p2;
    // init
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    // 建立生產者執行緒
    pthread_create(&p1, NULL, producer, NULL);
    // 建立消費者執行緒
    pthread_create(&p2, NULL, customer, NULL);

    // 阻塞回收子執行緒
    pthread_join(p1, NULL);
    pthread_join(p2, NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    return 0;
}

九十. 使用條件變數,實現生產者消費者模型