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); }
解决办法:就是互斥咯
互斥创建
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); }
ok!