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

目录

例一

分析

例二

分析

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;
}

 

分析

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

分别输出了 parent, daughter, son

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

 

例二

#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);
        }
    }
}

 

分析

父进程(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:为从文件当前位置的起始要锁住的长度。

 

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

参考

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

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
lockf函数用于对文件进行加锁和解锁操作,其函数原型为: ``` #include <unistd.h> int lockf(int fd, int cmd, off_t len); ``` 其中,参数fd是文件描述符,cmd是锁的类型,len是锁的长度。 cmd参数可取以下值: - F_LOCK:请求加锁,如果文件已经被其他进程锁定,则当前进程会阻塞等待。 - F_TLOCK:尝试加锁,如果文件已经被其他进程锁定,则当前进程不会阻塞,而是返回-1并设置errno为EAGAIN。 - F_ULOCK:解锁文件。 - F_TEST:测试文件是否能够加锁,如果文件已经被其他进程锁定,则当前进程不会阻塞,而是返回-1并设置errno为EAGAIN。如果文件可以加锁,则返回0。 len参数表示锁的长度,如果为0,则表示对整个文件进行加锁或解锁操作。 下面是一个使用lockf函数加锁的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> int main() { int fd, ret; char buf[1024]; // 打开文件 fd = open("test.txt", O_RDWR); if (fd < 0) { perror("open"); exit(1); } // 尝试加锁 ret = lockf(fd, F_TLOCK, 0); if (ret < 0) { if (errno == EAGAIN) { printf("file is locked by other process\n"); } else { perror("lockf"); exit(1); } } else { printf("file is locked\n"); } // 读取文件内容 lseek(fd, 0, SEEK_SET); read(fd, buf, sizeof(buf)); printf("file content: %s\n", buf); // 解锁文件 lockf(fd, F_ULOCK, 0); printf("file is unlocked\n"); // 关闭文件 close(fd); return 0; } ``` 在这个示例中,我们尝试对文件进行加锁操作,如果文件已经被其他进程锁定,则会返回-1并设置errno为EAGAIN。如果文件可以加锁,则会打印出"file is locked"。接着我们读取文件内容并输出,在完成操作后解锁文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泥烟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值