【Linux线程同步专题】五、进程间同步
欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起探讨和分享Linux C/C++/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。
专栏:《Linux从小白到大神》 | 系统学习Linux开发、VIM/GCC/GDB/Make工具、Linux文件IO、进程管理、进程通信、多线程等,请关注专栏免费学习。
1. 互斥量mutex
进程间也可以通过互斥锁来达到同步的目的。在pthread_mutex_init初始化之前需要修改属性为进程间共享。
1.1 互斥量属性对象的创建与销毁
- 头文件及函数原型
#include <pthread.h>
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
-
函数描述
- The pthread_mutexattr_destroy() function shall destroy a mutex attributes object; the object becomes, in effect, uninitialized.
- The pthread_mutexattr_init() function shall initialize a mutex attributes object attr with the default value for all of the attributes defined by the implementation.
-
函数参数
- attr:互斥量属性对象
-
函数返回值
Upon successful completion, pthread_mutexattr_destroy() and pthread_mutexattr_init() shall return zero; otherwise, an error number shall be returned to indicate the error.
1.2 属性的设置与获取
- 头文件及函数原型
#include <pthread.h>
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
-
函数描述
- The pthread_mutexattr_getpshared() function shall obtain the value of the process-shared attribute from the attributes object referenced by attr.
- The pthread_mutexattr_setpshared() function shall set the process-shared attribute in an initialized attributes object referenced by attr.
-
函数参数
- attr
- pshared
-
函数返回值
Upon successful completion, pthread_mutexattr_setpshared() shall return zero; otherwise, an error number shall be returned to indicate the error. Upon successful completion, pthread_mutexattr_getpshared() shall return zero and store the value of the process-shared attribute of attr into the object referenced by the pshared parameter. Otherwise, an error number shall be returned to indicate the error.
2. 文件锁
借助fcntl()函数来实现锁机制,操作文件的进程没有获得锁时,可以打开,但无法执行read和write操作。文件锁具有读写锁的特点,写独占,读共享,写优先级高。
- 头文件及函数原型
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
-
函数描述
fcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd. 获取、设置文件访问控制属性。
-
函数参数
- fd:文件描述符
- cmd:
- F_SETLK (struct flock *):设置文件锁trylock
- F_SETLKW (struct flock *):设置文件锁lock
- F_GETLK (struct flock *):获取文件锁
struct flock { ... short l_type; /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK 锁的类型 */ short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END 偏移位置 */ off_t l_start; /* Starting offset for lock 起始偏移 */ off_t l_len; /* Number of bytes to lock 长度,0表示整个文件加锁 */ pid_t l_pid; /* PID of process blocking our lock (F_GETLK only) 持有该锁的进程ID */ ... };
-
函数返回值
-
For a successful call, the return value depends on the operation:
-
F_DUPFD The new descriptor.
-
F_GETFD Value of flags.
-
F_GETFL Value of flags.
-
F_GETLEASE Type of lease held on file descriptor.
-
F_GETOWN Value of descriptor owner.
-
F_GETSIG Value of signal sent when read or write becomes possible, or zero for traditional SIGIO behavior.
All other commands Zero.
-
-
On error, -1 is returned, and errno is set appropriately.
-
用法示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define _FILE_PATH_ "/home/qq/dm/daemon/test.lock"
int main(int argc, char* argv[])
{
int fd = open(_FILE_PATH_, O_RDWR | O_CREAT, 0644);
if(fd < 0)
{
perror("open err");
return -1;
}
struct flock lk;
lk.l_type = F_WRLCK;
lk.l_whence = SEEK_SET;
lk.l_start = 0;
lk.l_len = 0;
if(fcntl(fd, F_SETLK, &lk) < 0)
{
perror("lock err");
exit(1);
}
while(1)
{
printf("pid: %d\n", getpid());
sleep(1);
}
return 0;
}
编译运行
此时我们再开一个终端运行上面的程序
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了