zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ",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
    ",strerror(err));
                exit(1);
            }   
        }   
        //收尸
        for(i = 0 ; i < THRNUM ; i++)
        {   
            pthread_join(tid[i],NULL);
        }   
        pthread_mutex_destroy(&mut);// 销毁互斥
        exit(0);
    }
    View Code

    ok!

  • 相关阅读:
    [知识点]计算几何I——基础知识与多边形面积
    [旧版][知识点]SPFA算法
    [旧版][知识点]A*搜索(启发式搜索)
    [知识点]线段树
    [小工具]ChemistryHelper
    [考试]20150314
    [知识点]Cantor展开
    [旧版][知识点]拓扑排序
    [无效]网络流之Dinic算法
    [SCOI2005]扫雷Mine
  • 原文地址:https://www.cnblogs.com/muzihuan/p/4694923.html
Copyright © 2011-2022 走看看