一个进程打开文件,并锁住该文件,另一个进程读取这部份数据,就进入锁等待.例如下面的程序:
源程序2:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <sys/stat.h>
const char *filename = "messagebuf.dat";
void error_out(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
void child(void)
{
FILE *fp = fopen(filename, "r+");
if (fp == NULL)
error_out("child:fopen");
int r = lockf(fileno(fp), F_LOCK, 0);
if (r == -1)
error_out("parent:lockf");
char buf[32];
fread(buf,sizeof(buf), 1, fp);
if (ferror(fp))
error_out("fread");
printf("child read '%s'\n", buf);
}
void parent(FILE *fp)
{
fprintf(fp, "%#x", getpid());
fflush(fp);
int r = lockf(fileno(fp), F_ULOCK, 0);
if (r == -1)
error_out("lockf:F_ULOCK");
fclose(fp);
}
int main(int argc, char *argv[])
{
int r;
int fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0666);
FILE *fp = fdopen(fd, "r+");
if (fp == NULL)
error_out("parent:fopen");
r = lockf(fileno(fp), F_LOCK, 0);
if (r == -1)
error_out("parent:lockf");
pid_t pid = fork();
if (pid == 0){
child();
exit(0);
}
else{
int status = 0;
parent(fp);
wait(&status);
printf("child status=%d\n", WEXITSTATUS(status));
}
unlink (filename);
exit(0);
}
gcc file-ipc-better.c -o file-ipc-better
./file-ipc-better
child read '0x4fa9'
child status=0
改进后的程序在创建子进程前创建了文件,并且利用lockf锁定了文件,当子进程打开文件后,发现文件已经在锁定状态,这时要等父进程写入完成,解锁后它才能处理.
父进程通过lockf对文件进行解锁,父进程通过这种办法可以保证文件内容在子进程读取之前的有效性,随后子进程对文件进行锁定,并完成读写.
我们通过lockf对父子进程通讯写入进行保护.
源程序2:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <sys/stat.h>
const char *filename = "messagebuf.dat";
void error_out(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
void child(void)
{
FILE *fp = fopen(filename, "r+");
if (fp == NULL)
error_out("child:fopen");
int r = lockf(fileno(fp), F_LOCK, 0);
if (r == -1)
error_out("parent:lockf");
char buf[32];
fread(buf,sizeof(buf), 1, fp);
if (ferror(fp))
error_out("fread");
printf("child read '%s'\n", buf);
}
void parent(FILE *fp)
{
fprintf(fp, "%#x", getpid());
fflush(fp);
int r = lockf(fileno(fp), F_ULOCK, 0);
if (r == -1)
error_out("lockf:F_ULOCK");
fclose(fp);
}
int main(int argc, char *argv[])
{
int r;
int fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0666);
FILE *fp = fdopen(fd, "r+");
if (fp == NULL)
error_out("parent:fopen");
r = lockf(fileno(fp), F_LOCK, 0);
if (r == -1)
error_out("parent:lockf");
pid_t pid = fork();
if (pid == 0){
child();
exit(0);
}
else{
int status = 0;
parent(fp);
wait(&status);
printf("child status=%d\n", WEXITSTATUS(status));
}
unlink (filename);
exit(0);
}
gcc file-ipc-better.c -o file-ipc-better
./file-ipc-better
child read '0x4fa9'
child status=0
改进后的程序在创建子进程前创建了文件,并且利用lockf锁定了文件,当子进程打开文件后,发现文件已经在锁定状态,这时要等父进程写入完成,解锁后它才能处理.
父进程通过lockf对文件进行解锁,父进程通过这种办法可以保证文件内容在子进程读取之前的有效性,随后子进程对文件进行锁定,并完成读写.
我们通过lockf对父子进程通讯写入进行保护.
转载于:https://blog.51cto.com/xuanjicto/725323