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!

posted @ 2015-08-01 23:41  muzihuan  阅读(2533)  评论(0编辑  收藏  举报