进程同步的方法
文章目录
本文介绍进程间同步的3种方法,分别是文件锁,信号量和互斥量。 并且介绍它们是如何实现进程间同步的。
1.1 文件锁(记录锁)
文件锁,在APUE中称为记录锁(record locking),是保证某一时刻只有一个进程修改文件中的一个指定区域的锁。
1.1.1 fcntl()
fcntl()函数原型:int fcntl(int fd, int cmd, struct flock* fllockptr)。
对于函数fcntl()来说,记录锁是通过cmd来控制的。记录锁的对应的cmd有:F_GETLK,F_SETLK和F_SETLKW。
flock结构体的定义如下:
|
|
flock结构中各个成员的含义说明:
-
l_type表示文件锁的类型:F_RDLCK表示共享读锁, F_WRLCK为独占写锁, F_UNLCK为解锁指定文件区域
-
l_whence, l_start和lseek()中的whence、offset功能相同;
1.1.2 文件锁的使用方法
-
对整个文件加锁的方法:将l_start和l_len都设置为0, l_whece设置为SEEK_SET。
-
如果一个进程对一个文件区域已经加了锁,后续如果该进程再次对同一区域再次加锁。则新锁将替换已持有的锁。
-
加读锁时,该文件描述符必须是读打开的。加写锁时,该描述符必须是写打开的。
fcntl函数中,文件锁三种参数的的说明:
F_GETLK:判断对flockptr指定的文件区域加锁是否可以会被阻塞。
F_SETLK:尝试获取一把锁,若无法获取锁,则返回错误码EACCES,EAGAIN。
F_SETLKW:这个命令是F_SETLK的阻塞版本(w表示wait)。锁所设置的文件区域已经加锁而我们又无法获取该锁时,那么当前进程会被阻塞。只有等请求的锁可用或者休眠被信号中断,该进程才会被唤醒。
1.1.3 文件锁的继承和释放
-
文件锁和进程、文件关联。以下几种场景都会关闭文件锁。
- 进程退出:当一个进程退出时,它所建立的锁全部关闭。
- 文件关闭:文件描述符关闭,则该文件关联的锁全部关闭。
-
由fork创建的子进程不继承父进程设置的锁。
-
在执行exec后,新程序可以继承原执行程序的锁。但是,如果文件设置了(O_CLOEXEC)。
1.2 信号量
信号量的使用方法见进程间通信文章中的相关内容。
1.3 互斥量
使用互斥量在多个进程之间实现同步,需要做如下处理:
-
多个进程之间需要使用共享内存。
-
互斥量需要在共享内存中中初始化;
-
互斥量的属性需要设置为PTHREAD_PROCESS_SHARED。
进程间使用互斥量的示例如下:
|
|