当前位置: 首页 > 科技观察

Linux系统编程——进程间同步

时间:2023-03-15 15:06:36 科技观察

我们知道线程同步的方式有很多种,比如:信号量、互斥量、读写锁等等。如何实现进程间的同步?本文介绍两种方法:互斥量和文件锁。##Mutexmutex我们已经知道互斥量可以用于线程间的同步,但其实互斥量也可以用于进程间的同步。为了达到这个目的,在pthread_mutex_init初始化之前,可以修改它的属性为进程间共享。mutex属性修改函数主要有以下几个:主应用函数:pthread_mutexattr_tmattr类型:用于定义mutex的属性pthread_mutexattr_init函数:初始化一个mutex属性对象pthread_mutexattr_destroy函数:销毁mutex属性对象(不销毁锁)pthread_mutexattr_setpshared函数:修改互斥量属性。intpthread_mutexattr_setpshared(pthread_mutexattr_t*attr,intpshared);我们重点看第二个参数:pshared,它有如下两个值:线程锁:PTHREAD_PROCESS_PRIVATE(mutex默认属性是线程锁,进程间私有)进程锁:PTHREAD_PROCESS_SHARED要实现进程间同步,需要将互斥量的属性更改为PTHREAD_PROCESS_SHARED。#include#include#include#include#include#include#include#includestructmt{intnum;pthread_mutex_tmutex;pthread_mutexattr_tmutexattr;};intmain(void){inti;structmt*mm;pid_tpid;mm=mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);memset(mm,0,sizeof(*mm));pthread_mutexattr_init(&mm->mutexattr);//初始化互斥属性对象pthread_mutexattr_setpshared(&mm->mutexattr,PTHREAD_PROCESS_SHARED);//修改属性为进程间共享pthread_mutex_init(&mm->mutex,&mm->mutexattr);//初始化一把mutex琴pid=fork();if(pid==0){for(i=0;i<10;i++){sleep(1);pthread_mutex_lock(&mm->mutex);(mm->num)++;pthread_mutex_unlock(&mm->mutex);printf("-child----------num++%d\n",mm->num);}}elseif(pid>0){for(i=0;i<10;i++){sleep(1);pthread_mutex_lock(&mm->mutex);mm->num+=2;pthread_mutex_unlock(&mm->静音x);printf("--------parent---num+=2%d\n",mm->num);}wait(NULL);}pthread_mutexattr_destroy(&mm->mutexattr);//销毁mutex属性对象pthread_mutex_destroy(&mm->mutex);//销毁mutexmunmap(mm,sizeof(*mm));//释放映射区return0;}##Filelock顾名思义就是实现锁机制通过文件。具体来说,就是使用fcntl函数来实现锁机制。当操作文件的进程没有获取到锁时,虽然可以打开文件,但是不能对该文件进行读写操作。###fcntl函数:函数原型:intfcntl(intfd,intcmd,.../arg/);功能:获取和设置文件访问控制属性。参数介绍:参数cmd取值如下:F_SETLK(structflock)setfilelock(trylock)F_SETLKW(structflock)setfilelock(lock)W-->waitF_GETLK(structflock*)getfilelockdatatypeflock原型如下:structflock{...shortl_type;锁类型:F_RDLCK,F_WRLCK,F_UNLCKshortl_whence;偏移位置:SEEK_SET,SEEK_CUR,SEEK_ENDoff_tl_start;起始偏移量:1000off_tl_len;length:0表示整个文件被锁定pid_tl_pid;持有锁的进程ID:(仅限F_GETLK)...};###Interprocessfilelockexample多个进程访问锁定的文件:#include#include#include#include#include#includevoidsys_err(char*str){perror(str);exit(1);}intmain(intargc,char*argv[]){intfd;structflockf_lock;if(argc<2){printf("./a.outfilename\n");exit(1);}if((fd=open(argv[1],O_RDWR))<0)sys_err("open");f_lock.l_type=F_WRLCK;/*选择写锁*///f_lock.l_type=F_RDLCK;/*选择读锁*/f_lock.l_whence=SEEK_SET;f_lock.l_start=0;f_lock.l_len=0;/*0表示整个文件被锁定*/fcntl(fd,F_SETLKW,&f_lock);printf("getflock\n");sleep(10);f_lock.l_type=F_UNLCK;fcntl(fd,F_SETLKW,&f_lock);printf("unflock\n");close(fd);return0;}文件锁与读写锁类似,仍然遵循“读共享,写独占”的特性。但是如果进程不加锁直接操作文件,还是可以访问成功的,但是数据势必会混乱。既然文件锁可以用在进程中,那么文件锁可以用在多线程中吗?答案是不。因为文件描述符是多个线程共享的,所以锁定文件是通过修改文件描述符指向的文件结构中的成员变量来实现的。所以在多线程中不能使用文件锁。