日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

多線程加鎖

 mrjbydd 2012-08-24

Linux pthread_mutex演示程序

Linux pthread 中使用mutex 進行互斥的程序和結(jié)果

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "pthread.h"


#define THREAD_NUMBER 2

int sum = 0;

void* fun(void* arg) {
    int t = (*(int*)arg);
    int i;
    for (i = t ;i < 10000; i += 2)
         sum = sum + i;
    return NULL;
}

int main(){
     pthread_t T[THREAD_NUMBER];
    int arg[THREAD_NUMBER];
    int ret,i;
    void* join_result;
    
    for (i =0 ;i < THREAD_NUMBER; ++ i){
         arg[i] = i;
         ret = pthread_create(&T[i],NULL,fun,(void*)&arg[i]);
        if (ret){
             printf("Thread %d crreate failure!\n",i);
             exit(EXIT_FAILURE);
         }
     }
    for (i = 0 ;i < THREAD_NUMBER; ++ i){
         ret = pthread_join(T[i],&join_result);
        if (ret) {
             printf("Thread %d join failure!\n",i);
             exit(EXIT_FAILURE);
         }
     }
     printf("sum = %d\n",sum);
    return 0;
}

上面的程序是沒有進行互斥的 nomutex.c 該程序用于求 1...9999的和,可以gcc -l pthreacd -o test nomutex.c編譯該程序,
并且可以實驗運行結(jié)果基本上都是不對的,由于該程序沒有應(yīng)用互斥操作,所以可想而知為什么結(jié)果是不對的。

下面的程序就在上面程序的基礎(chǔ)上加上了求和時的互斥操作,所以運行結(jié)果都是對的。
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "pthread.h"


#define THREAD_NUMBER 2

int sum = 0;

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* fun(void* arg) {
    int t = (*(int*)arg);
    int i;
    for (i = t ;i < 10000; i += 2) {
         pthread_mutex_lock(&mutex);
         sum = sum + i;
         pthread_mutex_unlock(&mutex);
     }
    return NULL;
}

int main(){
     pthread_t T[THREAD_NUMBER];
    int arg[THREAD_NUMBER];
    int ret,i;
    void* join_result;
    
    for (i =0 ;i < THREAD_NUMBER; ++ i){
         arg[i] = i;
         ret = pthread_create(&T[i],NULL,fun,(void*)&arg[i]);
        if (ret){
             printf("Thread %d crreate failure!\n",i);
             exit(EXIT_FAILURE);
         }
     }
    for (i = 0 ;i < THREAD_NUMBER; ++ i){
         ret = pthread_join(T[i],&join_result);
        if (ret) {
             printf("Thread %d join failure!\n",i);
             exit(EXIT_FAILURE);
         }
     }
     printf("sum = %d\n",sum);
    return 0;
}
用這兩個小程序,只是想演示一下linuxpthread 的互斥操作??梢钥吹?,在多線程環(huán)境中,為了保證共享變量的值的正確性,
互斥是非常重要的。



我覺得應(yīng)該加鎖。理由如下:
     比如說有多個線程都要讀一個文件。
     先要open 打開一個文件,得到一個fd

對任一個讀線程來說操作如下:
     1. lseek(fd..)到適當?shù)奈恢?BR style="WORD-WRAP: break-word">     2. read(fd..)

雖然以上每一個都是原子操作,可是1,2之間是可以中斷的。如果線程一lseek了之后,系統(tǒng)暫時掛起線程1,運行線程二,線程也調(diào)用lseek。

內(nèi)核給每一個進程有一個進程描述結(jié)構(gòu),在Linux中task_struct,在FreeBSD中是proc,存放每一個進程的信息。(下面以FreeBSD為例,因為linux不太清楚,原理應(yīng)該是一樣的).
proc里有一個struct filedesc,這里存放一個進程所有打開的文件的信息。它里面有一個struct file的表,每一個表表示這個進程一個打開文件。struct file里面記錄了調(diào)用lseek設(shè)定的這個文件offset大小,對這個文件的讀寫都是從這里開始的。也就是說這個offset實際上是進程的各個線程共享的。
如果出現(xiàn)像上面說的那種情況,線程一設(shè)定的offset就被線程二給修改了。當線程一再開始運行的時候,讀到的數(shù)據(jù)肯定是錯誤的。

所以說,為了數(shù)據(jù)的正確性,多線程讀一個文件也應(yīng)該加鎖。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多