运行环境:请在Linux下进行编译测试
该程序是使用C语言编写的一个简单的文件锁示例的程序。它创建了一个名为"locked_file.txt"的文件,并向其中写入一些文本内容。然后它创建了两个子进程(p1和p2),每个子进程都会对文件进行加锁并写入一些文本内容,然后解锁该文件。父进程也会对文件进行加锁并写入文本内容,然后解锁文件。
程序使用了标准库函数`open`、`fork`、`write`、`sleep`、`lockf`、`lseek`和`close`,它的主要目的是展示多个进程对同一个文件进行加锁和解锁的过程。
其它需要注意的是,这段代码中使用了`fork`函数创建子进程,而`wait`函数用于在父进程中等待子进程结束。此外,`lockf`函数实现了对文件的加锁和解锁操作。
值得一提的是,尽管C语言中也可以实现文件锁的功能,但在实际的生产环境中,更常用的做法是借助更高级的工具或库来实现文件的锁定,如使用POSIX文件锁或者专门用于文件锁管理的库函数,那么,我们就下面就开始操作。
1、首先我们在Linux或者UNIX中打开终端,创建一个名为“3”的文件夹,然后创建一个名为“3.c”的c文件,并且将下方的程序写入并按“esc”输入“:wq”保存退出
创建文件夹命令:mkdir 3
创建3.c文件命令:vi 3.c或vim 3.c
将下方程序写入:
#include<fcntl.h>
#include<stdio.h>
int fatal(const char *info)
{
perror(info);
exit(1);
}
int lock(int fd)
{
lseek(fd, 0, SEEK_SET);
if (lockf(fd, F_LOCK, 0) == -1)
fatal("lockf()");
return 0;
}
int unlock(int fd)
{
lseek(fd, 0, SEEK_SET);
if (lockf(fd, F_ULOCK, 0) == -1)
fatal("unlockf()");
return 0;
}
int main()
{
int fd;
int p1, p2, i;
char str[20];
if ((fd = open("locked_file.txt", O_RDWR | O_APPEND | O_CREAT, 0666)) < 0)
fatal("open");
write(fd, "=========\n", 10);
while ((p1 = fork()) == -1);
if (p1 == 0)
{
lock(fd);
for (i = 0; i < 3; i++)
{
sprintf(str, "daughter %d\n", i);
write(fd, str, strlen(str));
sleep(1);
}
unlock(fd);
}
else
{
while ((p2 = fork()) == -1);
if (p2 == 0)
{
lock(fd);
for (i = 0; i < 3; i++)
{
sprintf(str, "son %d\n", i);
write(fd, str, strlen(str));
sleep(1);
}
unlock(fd);
}
else
{
lock(fd);
for (i = 0; i < 3; i++)
{
sprintf(str, "parent %d\n", i);
write(fd, str, strlen(str));
sleep(1);
}
unlock(fd);
wait(NULL);
wait(NULL);
}
}
close(fd);
}
按“esc”输入“:wq”保存退出
2、我们对文件进行编译命令如下
编译命令:gcc 3.c -o 3
我们会发现有警告“warning”,警告不影响,如果出现了“error”有错误就无法进行编译,那么我们就要进行排错
//在此处我们制定了编译后的文件名为3
如果我们没有加“-o”的指令,那么输出的文件就是a.out
接下来我们就运行编译后的文件,命令格式“./+文件名”,例如文件“3”执行命令如下:
执行命令:./3
3、运行后我们发现会多出一个名为“locked_file.txt”的文本文件,这就是上方的程序代码运行后向文本文件中写入的父进程与子进程,我们使用vi命令打开这个文本文件
命令:vi locked_file.txt
打开后我们发现输出了几行的字符
那么其中的parnet也就是我们程序中的父进程
daughter是程序中int整型变量p1子进程写入的内容
那么son就是程序中int整型变量p2写入的内容,其中\n为换行符