当前位置: 首页 > Linux

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

时间:2023-04-06 18:52:46 Linux

我们知道线程同步的方式有很多种,比如:信号量、互斥量、读写锁等等。如何实现进程间的同步?本文介绍两种方式:mutex和filelock。我们已经知道互斥量可以用于线程间的同步,但实际上互斥量也可以用于进程间的同步。为了达到这个目的,在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_t互斥;pthread_mutexattr_tmutexattr;};intmain(void){inti;结构山*毫米;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);//初始化一个互斥锁pid=fork();如果(pid==0){对于(i=0;i<10;i++){睡眠(1);pthread_mutex_lock(&mm->mutex);(mm->num)++;pthread_mutex_unlock(&mm->互斥体);printf("-child--------num++%d\n",mm->num);}}elseif(pid>0){for(i=0;i<10;i++){睡眠(1);pthread_mutex_lock(&mm->mutex);mm->num+=2;pthread_mutex_unlock(&mm->mutex);printf("------父级---num+=2%d\n",mm->num);}等待(NULL);}pthread_mutexattr_destroy(&mm->mutexattr);//销毁互斥属性对象pthread_mutex_destroy(&mm->mutex);//销毁互斥量munmap(mm,sizeof(*mm));//释放映射区return0;}顾名思义,文件锁就是通过文件来实现锁机制。具体来说,锁机制是使用fcntl函数实现的。当操作文件的进程没有获取到锁时,虽然可以打开文件,但是不能对该文件进行读写操作。fcntl函数:函数原型:intfcntl(intfd,intcmd,.../arg/);功能:获取和设置文件访问控制属性。参数介绍:参数cmd取值如下:F_SETLK(structflock*)设置文件锁(trylock)F_SETLKW(structflock*)设置文件锁(lock)W-->waitF_GETLK(structflock*)获取文件锁数据类型flock原型如下:structflock{...shortl_type;锁类型:F_RDLCK,F_WRLCK,F_UNLCK简称l_whence;偏移位置:SEEK_SET,SEEK_CUR,SEEK_ENDoff_tl_start;起始偏移量:1000off_tl_len;Length:0表示整个文件被锁定pid_tl_pid;持有锁的进程ID:(仅限F_GETLK)...};进程间文件锁示例多个进程访问锁定的文件:#include#include#include#include#include#includevoidsys_err(char*str){错误(海峡);退出(1);}intmain(intargc,char*argv[]){intfd;结构群f_lock;如果(argc<2){printf("./a.out文件名\n");退出(1);}如果((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("得到羊群\n");睡眠(10);f_lock.l_type=F_UNLCK;fcntl(fd,F_SETLKW,&f_lock);printf("unflock\n");关闭(fd);但是如果进程不加锁直接操作文件,还是可以访问成功的,但是数据势必会混乱。既然文件锁可以用在进程中,那么文件锁可以用在多线程中吗?答案是不。因为文件描述符是多个线程共享的,所以锁定文件是通过修改文件描述符指向的文件结构中的成员变量来实现的。所以在多线程中不能使用文件锁。更多精彩内容,关注公众号良旭Linux,在公众号回复1024免费领取5T技术资料,包括:Linux、C/C++、Python、树莓派、嵌入式、Java、人工智能等。公众号回复加群,邀你加入达人如云技术交流群。最后,最近有很多朋友找我要一份Linux学习路线图,所以我结合自己的经验,利用业余时间熬夜一个月,整理了一本电子书。无论你是面试还是自我提升,相信都会对你有所帮助!免费送给大家,只求大家给我点个赞!电子书|LinuxDevelopmentLearningRoadmap也希望有小伙伴可以和我一起把这本电子书做得更完美!获得?希望老铁们来个三连击,让更多人看到这篇文章。推荐阅读:干货|程序员和高级架构师免费发送工件的必备资源|支持搜索的资源网站