2017年3月22日 星期三

thread - pthread (POSIX Threads) linux 實作 基礎互斥鎖(Mutex)

在之前的blog (thread & process)中有稍微提到thread一些要注意的事項,而Mutex 就是可以有效的解決thread 同步的問題。
簡單來說 thread 最常遇到的問題就是共用資源分配的問題,當你設計multi-threads時有特別是利用到global variable (全域變數時),要特別注意同步及資源的問題(Race Condition、Critical Section),否則很容易對你自己create 的 thread 無法掌握,造成 random issues。

Mutex 常用 API

pthread_mutex_init() 初始化互斥鎖
pthread_mutex_destroy() 刪除互斥鎖

pthread_mutex_lock():占有互斥鎖(阻塞操作)
pthread_mutex_trylock():試圖占有互斥鎖(不阻塞操作)。即,當互斥鎖空閒時,將占有該鎖;否則,立即返回。
具體說一下trylock函數, 這個函數是非阻塞呼叫模式, 也就是說, 如果互斥量沒被鎖住, trylock函數將把互斥量加鎖, 並獲得對共享資源的訪問權限; 如果互斥量被鎖住了, trylock函數將不會阻塞等待而直接返回EBUSY, 表示共享資源處於忙狀態。

pthread_mutex_unlock(): 釋放互斥鎖

由 example-1 可以觀察到 mutex API 簡單的範例,創建兩個threads對sum從1加到100。前面第一個線程從1-49,后面從50-100。主線程讀取最后的加值。為了防止資源競爭,用了pthread_mutex_t 鎖操作。
example-1中主程式中有一段 sleep(1),可以觀察到若沒有加入讓他主程式delay 一會,得到的結果不會是預想的結果從1累加到100,這也是設計thread時必須考慮到的。


Example-1

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
typedef struct ct_sum
{   int sum;
    pthread_mutex_t lock;
}ct_sum;
void * add1(void * cnt)
{    
    printf("pthread add1 !!\n");
    pthread_mutex_lock(&(((ct_sum*)cnt)->lock));
printf("pthread add1 get key!!\n");
    int i;
        for( i=0;i<50;i++){
            (*(ct_sum*)cnt).sum+=i;
}
    pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));
    pthread_exit(NULL);
    return 0;
}
void * add2(void *cnt)
{
printf("pthread add2 !!\n");    
    int i;
    cnt= (ct_sum*)cnt;
    pthread_mutex_lock(&(((ct_sum*)cnt)->lock));
printf("pthread add2 get key!!\n");
    for( i=50;i<101;i++)
    {  
(*(ct_sum*)cnt).sum+=i;      
    }
    pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));
    pthread_exit(NULL);
    return 0;
}
int main(void)
{   int i;
    pthread_t ptid1,ptid2;
    int sum=0;
    ct_sum cnt;
    pthread_mutex_init(&(cnt.lock),NULL);
    cnt.sum=0;
    pthread_create(&ptid1,NULL,add1,&cnt);
    pthread_create(&ptid2,NULL,add2,&cnt);
    //sleep(1);
    pthread_mutex_lock(&(cnt.lock));
printf("main proccess get key!!\n");
    printf("sum %d\n", cnt.sum);
    pthread_mutex_unlock(&(cnt.lock));
    pthread_join(ptid1,NULL);
printf("join ptid1\n");
    pthread_join(ptid2,NULL);
printf("join ptid2\n");
    pthread_mutex_destroy(&(cnt.lock));
    return 0;
}

reference:wiki_pthreadh's 手扎_pthread 立你斯學習紀錄-pthread mutex

沒有留言:

張貼留言

linux - IPC (inter-processes communication) Shered mempry(共用記憶體)

IPC (inter-processes communication) 顧名思義,processes 之間溝通的管道&機制。 Shared memory   程式間可以共享memory Message Queue  程式間傳送資訊最簡單的方法 Semaphore...