小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

多線程加鎖

 mrjbydd 2012-08-24

Linux pthread_mutex演示程序

Linux pthread 中使用mutex 進(jìn)行互斥的程序和結(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;
}

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

下面的程序就在上面程序的基礎(chǔ)上加上了求和時(shí)的互斥操作,所以運(yùn)行結(jié)果都是對(duì)的。
#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;
}
用這兩個(gè)小程序,只是想演示一下linuxpthread 的互斥操作??梢钥吹?,在多線程環(huán)境中,為了保證共享變量的值的正確性,
互斥是非常重要的。



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

對(duì)任一個(gè)讀線程來(lái)說(shuō)操作如下:
     1. lseek(fd..)到適當(dāng)?shù)奈恢?BR style="WORD-WRAP: break-word">     2. read(fd..)

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

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

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

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多