linux高編線程-------線程:競爭,互斥量---多線程對同一文件讀寫問題


當多個控制線程共享相同的內存時呢,需要確保每個線程看到一致的數據視圖。

如果每個線程使用的變量都是其他線程不會讀取和修改,那么就不存在一致性的問題。

線程互斥接口用來保護數據,用於確保同一時間只有一個線程訪問數據。

互斥:限制代碼---獨占

很久以前:

下面程序存在競爭問題的喲,當創建20個線程,每個線程都對同一個文件進行讀寫操作,有可能發生N個線程同時對文件進行打開和讀操作,在寫的過程可能會對同一個數重復進行+1操作。比如說讀到  1, 然后N個線程取到1 並對1這個數做+1操作。

/*
    實現20個線程分別向/tmp/out寫+1操作
    問題:運行結果應該為21,對於多核設備,運行會存在競爭,運行結果不確定
    (多個線程打開文件)
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#define THRNUM      20  //線程數量
#define MAXLINE     1024//從文件讀最大字節數
#define FILENAME    "/tmp/out"
void * thr_add(void *p) 
{
    FILE * fp; 
    char linebuf[MAXLINE];
    //open
   fp = fopen(FILENAME , "r+");
   if(fp == NULL )
   {         
        perror("fopen()");
        exit(1);
   }   
    //read
    fgets(linebuf,MAXLINE,fp);
    //write
    rewind(fp);//文件偏移量設備文件開始位置
    fprintf(fp,"%d\n",atoi(linebuf)+1);
    //close
    fclose(fp);
    pthread_exit(NULL);
}


int main()
{

    int i , err;
    pthread_t tid[THRNUM];
    //創建線程
    for(i = 0 ; i < THRNUM ; i++)
    {   
        err = pthread_create(tid+i,NULL,thr_add,NULL);
        if(err)
        {   
            fprintf(stderr , "pthread_create():%s\n",strerror(err));
            exit(1);
        }   
    }   
    //收屍
    for(i = 0 ; i < THRNUM ; i++)
    {
        pthread_join(tid[i],NULL);
    }   
View Code

 

解決辦法:就是互斥咯

互斥創建

       int pthread_mutex_destroy(pthread_mutex_t *mutex);//互斥量銷毀
       int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);//動態初始化:參數1:變量;參數2:屬性;
       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//靜態初始化

加鎖和解鎖:

       int pthread_mutex_lock(pthread_mutex_t *mutex);//阻塞
       int pthread_mutex_trylock(pthread_mutex_t *mutex);//
       int pthread_mutex_unlock(pthread_mutex_t *mutex);//解鎖

so,程序修改為:給他加上鎖

#include <pthread.h>
#include <string.h>
#define THRNUM      20  //線程數量
#define MAXLINE     1024//從文件讀最大字節數
#define FILENAME    "/tmp/out"

static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;//定義個鎖

void * thr_add(void *p) 
{
    FILE * fp; 
    char linebuf[MAXLINE];
    //open
   fp = fopen(FILENAME , "r+");
   if(fp == NULL )
   {         
        perror("fopen()");
        exit(1);
   }   
    pthread_mutex_lock(&mut);
    //read
    fgets(linebuf,MAXLINE,fp);
    //write
    rewind(fp);//文件偏移量設備文件開始位置
    fprintf(fp,"%d\n",atoi(linebuf)+1);
    //close
    fclose(fp);
    pthread_mutex_unlock(&mut);
    pthread_exit(NULL);
}


int main()
{

    int i , err;
    pthread_t tid[THRNUM];
    //創建線程
    for(i = 0 ; i < THRNUM ; i++)
    {   
        err = pthread_create(tid+i,NULL,thr_add,NULL);
        if(err)
        {   
            fprintf(stderr , "pthread_create():%s\n",strerror(err));
            exit(1);
        }   
    }   
    //收屍
    for(i = 0 ; i < THRNUM ; i++)
    {   
        pthread_join(tid[i],NULL);
    }   
    pthread_mutex_destroy(&mut);// 銷毀互斥
    exit(0);
}
View Code

ok!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM