进程如何同步你造了么
前言:线程如何同步应该知道了吧?不知道也没关系,可以参考我的这篇博客:https://www.cnblogs.com/liudw-0215/p/9685498.html,带你get线程同步。那进程如何同步呢?将介绍两种方式:互斥锁、文件锁,由我娓娓道来。
一、互斥锁
1、介绍
一看到互斥锁,就会想到线程也用这个方法同步,那怎么应用到进程呢?
进程间也可以使用互斥锁,来达到同步的目的。但应在pthread_mutex_init初始化之前,修改其属性为进程间共享。
2、主要函数
pthread_mutexattr_t mattr 类型: 用于定义mutex锁的【属性】
(1)pthread_mutexattr_init函数
初始化一个mutex属性对象
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
(2)pthread_mutexattr_destroy函数
销毁mutex属性对象 (而非销毁锁)
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
(3)pthread_mutexattr_setpshared函数
修改mutex属性。
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
参2:pshared取值:
线程锁:PTHREAD_PROCESS_PRIVATE (mutex的默认属性即为线程锁,进程间私有)
进程锁:PTHREAD_PROCESS_SHARED
主要就是要用这个pthread_mutexattr_setpshared函数,将属性设置为进程间共享。
3、示例程序
程序如下:

#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <sys/mman.h> #include <sys/wait.h> struct mt { int num; pthread_mutex_t mutex; pthread_mutexattr_t mutexattr; }; int main(void) { int i; struct mt *mm; pid_t pid; /* int fd = open("mt_test", O_CREAT | O_RDWR, 0777); ftruncate(fd, sizeof(*mm)); mm = mmap(NULL, sizeof(*mm), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); close(fd); unlink("mt_test"); */ 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); //初始化mutex属性对象 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++) { pthread_mutex_lock(&mm->mutex); (mm->num)++; pthread_mutex_unlock(&mm->mutex); printf("-child----------num++ %d\n", mm->num); } } else if (pid > 0) { for ( i = 0; i < 10; i++) { // sleep(1); pthread_mutex_lock(&mm->mutex); mm->num += 2; pthread_mutex_unlock(&mm->mutex); printf("-------parent---num+=2 %d\n", mm->num); } wait(NULL); } pthread_mutexattr_destroy(&mm->mutexattr); //销毁mutex属性对象 pthread_mutex_destroy(&mm->mutex); //销毁mutex munmap(mm,sizeof(*mm)); //释放映射区 return 0; }
二、文件锁
1、fcntl函数
文件锁的实现主要就是通过fcntl函数来实现的,所以先来介绍这个函数。
功能:借助 fcntl函数来实现锁机制。 操作文件的进程没有获得锁时,可以打开,但无法执行read、write操作。
原型:int fcntl(int fd, int cmd, ... /* arg */ );
参数说明:
参数1:文件描述符
参数2:
F_SETLK (struct flock *) 设置文件锁(相当于trylock,不成功直接返回)
F_SETLKW (struct flock *) 设置文件锁(相当于lock,不成功一直阻塞)W --> wait
F_GETLK (struct flock *) 获取文件锁
struct flock {
...
short l_type; 锁的类型:F_RDLCK 、F_WRLCK 、F_UNLCK
short l_whence; 偏移位置:SEEK_SET、SEEK_CUR、SEEK_END
off_t l_start; 起始偏移:1000
off_t l_len; 长度:0表示整个文件加锁
pid_t l_pid; 持有该锁的进程ID:(F_GETLK only)
...
};
2、示例程序
程序如下:

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> void sys_err(char *str) { perror(str); exit(1); } int main(int argc, char *argv[]) { int fd; struct flock f_lock; if (argc < 2) { printf("./a.out filename\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("get flock\n"); sleep(10); f_lock.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &f_lock); printf("un flock\n"); close(fd); return 0; }
总结:喜欢的帮忙推荐一下,在此谢过了;欢迎评论,交流与学习
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端