目录

​例一​


​分析​

​例二​

​分析​

​lockf()​

​参考​


例一

#include<stdio.h>                                                                           
#include<unistd.h>

{
int p1, p2, i;
while((p1=fork())==-1);
if(p1 == 0){
printf("1, pid=%d\n", getpid());
for(int i = 0; i < 10; i ++)
printf("daughter\n");
}else{
while((p2=fork())==-1);
if(p2 == 0){
printf("2, pid=%d\n", getpid());
for(int i = 0; i < 10; i ++)
printf("son\n");
}else{
printf("0, pid=%d\n", getpid());
for(int i = 0; i < 10; i ++)
printf("parent\n");
}
}
return 0;
}

[操作系统自由练习] 进程的同步,lockf()函数_c语言

 

分析

(图一)父进程(pid=51446)先后创建子进程1(pid=51447)和子进程2(pid=51448)

分别输出了 parent, daughter, son

并且在他们各自输出的时候, IO这一资源对于三个进程均可用, 多次运行该程序会看到如下交替输出的情况

[操作系统自由练习] 进程的同步,lockf()函数_c语言_02

 


例二

#include<stdio.h>
#include<unistd.h>
main() {
int p1, p2, i;
while((p1=fork())==-1);
if(p1 == 0){
lockf(1, 1, 0);//加锁
printf("1, pid=%d\n", getpid());
for(int i = 0; i < 10; i ++)
printf("daughter\n");
lockf(1, 0, 0);
}else{
while((p2=fork())==-1);
if(p2 == 0){
lockf(1, 1, 0);
printf("2, pid=%d\n", getpid());
for(int i = 0; i < 10; i ++)
printf("son\n");
lockf(1, 0, 0);
}
}
}

[操作系统自由练习] 进程的同步,lockf()函数_子进程_03

 

分析

父进程(pid=51716)先后创建子进程1(pid=51717)和子进程2(pid=51718)

与例一不同的是, 这里使用了lockf(), 对IO加锁, 不会再出现交替输出的情况, 实现互斥

  • 这里的lockf(1, 1, 0) 锁定的屏幕的输出, 其他进程此时无法输出
  • lockf(1, 0, 0)解锁屏幕输出


lockf()

函数原型

int lockf(int fd, int cmd, off_t len);

  • fd为通过open返回的打开文件描述符。
  • cmd的取值为:
  • F_LOCK:给文件互斥加锁,若文件以被加锁,则会一直阻塞到锁被释放。
  • F_TLOCK:同F_LOCK,但若文件已被加锁,不会阻塞,而回返回错误。
  • F_ULOCK:解锁。
  • F_TEST:测试文件是否被上锁,若文件没被上锁则返回0,否则返回-1。
  • len:为从文件当前位置的起始要锁住的长度。

[操作系统自由练习] 进程的同步,lockf()函数_c语言_04

 

可见进程终止时,他所建立的所有文件锁都会被释放(虽然子进程没解锁, 但是父进程最后还是完成输出操作)

参考

​>>>linux中fcntl()、lockf、flock的区别-lvyilong316-ChinaUnix博客​