lockf函数,熟悉((操作系统-管道通信(无名)))的进来看看程序,高分++
lockf函数,熟悉((操作系统-管道通信(无名)))的进来看看程序,高分++详细介绍
本文目录一览: lockf 函数的用法
lockf()函数允许将文件区域用作信号量(监视锁),或用于控制对锁定进程的访问(强制模式记录锁定)。试图访问已锁定资源的其他进程将返回错误或进入休眠状态,直到资源解除锁定为止。当关闭文件时,将释放进程的所有锁定,即使进程仍然有打开的文件。当进程终止时,将释放进程保留的所有锁定。
此函数调用成功后,将返回值 0,否则返回?1,并且设置 errno 以表示该错误。 由于当文件的某部分被其他进程锁定后,变量 errno 将会设置为[EAGAIN]而不是[EACCES]。
lockf 函数的用法是什么?
fopen("...","...")
第一个参数是指向一个文件,如果当前文件不存在,系统会创建这个文件名。第二个参数是对这个文件进行的操作。例如,只读,读写,写等。
请参看下面的程序,了解其具体用法。下面程序实现的是在zhubihui.txt中写入创建子程序的结果。
#include
#include
#include
main()
{
int p1,p2,i;
FILE *fp;
fp=fopen("zhubihui.txt","w+");
if(fp==NULL)
{printf("Fail to create file");
exit(-1);
}
while((p1=fork())==-1);
if(p1==0)
{lockf((int)fp,1,0);
for(i=0;i<10;i++)
fprintf(fp,"daughter%d\n",i);
lockf((int)fp,0,0);
}
else
{while((p2=fork())==-1);
if(p2==0)
{lockf((int)fp,1,0);
for(i=0;i<10;i++)
fprintf(fp,"son%d\n",i);
lockf((int)fp,0,0);
}
else
{
wait(NULL);
lockf((int)fp,1,0);
for(i=0;i<10;i++)
fprintf(fp,"parent%d\n",i);
lockf((int)fp,0,0);
}
}
fclose(fp);
}
谈谈linux中flock,lockf和fcntl的区别
首先flock和fcntl是系统调用,而lockf是库函数。lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文件加锁的效果也是一样的。
具体:
http://blog.uouo123.com/post/884.html
用lockf函数对文件加锁,lockf函数的第一个参数怎么写?
第一个参数是 int型的文件描述符fd,不是FILE* fp。可使用fileno()函数转换:int fd = fileno(fp);希望能帮到你!
编程高手。帮我详细解答下。
#include
#include
#include
void waiting(),stop(); /*声明两个函数因为不是int类型的函数必须提前声明才能调用。*/
int wait_mark; /*定义全局变量为了程序停止标志*/
main()
{
int p1,p2;
if(p1=fork()) /*启动一个子进程,并判断返回值,父进程时返回值是子进程号大于0,接着执行下面if大括号内的内容,子进程不会执行。*/
{
if(p2=fork()) /*启动另一个子进程。*/
{
wait_mark=1; /*将全局变量设置为1为了使waiting函数不会退出。*/
signal(SIGINT,stop); /*设置信号函数处理方式,当收到键盘发送键盘中断(如break键被按下)信号时调用stop函数。*/
waiting(); /*进入循环等待状态*/
kill(p1,16); /*向子进程1发送信号16以中断子进程。*/
kill(p2,17); /*向子进程2发送信号17以中断子进程。*/
wait(0); /*wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。*/
wait(0); /**/
printf("parent process is killed!\n"); /*打印父进程结束消息到屏幕。*/
exit(0);
}
else /*如果目前执行的是子进程p2,得到的fork()返回值是0,所以子进程p2将执行else下面的内容,父进程不会执行。*/
{
wait_mark=1; /*将全局变量设置为1为了使waiting函数不会退出。*/
signal(SIGINT, SIG_IGN); /*设置信号函数处理方式,当收到键盘发送键盘中断(如break键被按下)信号时将会忽略此信号。*/
signal(17,stop); /*设置信号函数处理方式,当收到系统发来的17信号时将调用stop函数。*/
waiting(); /*进入循环等待状态*/
lockf(1,1,0); /*锁定屏幕输出,防止两个进程同抢。*/
printf("child process2 is killed by parent!\n"); /*子进程p2输出。*/
lockf(1,0,0); /*解锁。*/
exit(0);
}
}
else /*如果目前执行的是子进程p1,得到的fork()返回值是0,所以子进程p1将执行else下面的内容,父进程不会执行。*/
{
wait_mark=1; /*将全局变量设置为1为了使waiting函数不会退出。*/
signal(SIGINT, SIG_IGN); /*设置信号函数处理方式,当收到键盘发送键盘中断(如break键被按下)信号时调用stop函数。*/
signal(16,stop); /*设置信号函数处理方式,当收到系统发来的17信号时将调用stop函数。*/
waiting(); /*进入循环等待状态*/
lockf(1,1,0); /*锁定屏幕输出,防止两个进程同抢。*/
printf("child process1 is killed by parent!\n"); /*子进程p1输出。*/
lockf(1,0,0); /*解锁。*/
exit(0);
}
}
void waiting() /*使程序进入循环等待状态,防止程序退出。*/
{
while (wait_mark!=0); /*循环判断全局变量wait_mark是否为0,为0时退出。*/
}
void stop() /*回调函数,当父进程收到键盘中断信号时执行,子进程收到父进程发来的信号16、17时执行*/
{
wait_mark=0; /*设置全局变量为0,使waiting()函数退出。*/
}
编译:
原文39行有一个signal写成了singnal会引起编译时链接不过。
执行:
程序执行后没有提示,按ctr-c后出现
child process1 is killed by parent!
child process2 is killed by parent!
parent process is killed!
3行输出信息。
程序演示了如何启动多进程,如何在子进程处理事件,父进程与子进程间如何通过信号通信。
这还不够详细吗?
熟悉((操作系统-管道通信(无名)))的进来看看程序,高分++
#include
main()
{
int i,r,p1,p2,fd[2];
char buf[50],s[50];
pipe(fd); //创建匿名管道,fd[0]为读端,fd[1]为写端
while((p1=fork())==-1); //创建子进程P1,直至成功为止(p1!=-1)
if(p1==0) //子进程P1执行逻辑
{
lockf(fd[1],1,0); //锁定管道写端,保证写入数据的完整性
sprintf(buf,"child process P1 is sending messages!\n"); //在buf中填入准备写入管道的信息数据
printf("child processP1!\n"); //打印“子进程P1正在运行”
write(fd[1],buf,50); //向管道写端fd[1]写入buf中的数据,写完后该数据即可以从读端fd[0]读出
sleep(5); //睡眠5秒
lockf(fd[1],0,0); //解锁管道写端
exit(0); //子进程P1退出
}
else //主进程的执行逻辑
{
while((p2=fork())==-1); //创建第二个子进程P2
if(p2==0) //子进程P2的执行逻辑
{
lockf(fd[1],1,0); //锁定管道写端,保证数据写入完整
sprintf(buf,"child process P2 is sending messages!\n"); //在buf中填入准备写入管道的信息数据
printf("child processP2!\n"); //打印“子进程P2正在运行”
write(fd[1],buf,50); //向管道写端fd[1]写入buf中的数据,写完后该数据即可从读端fd[0]读出
sleep(5); //睡眠5秒
lockf(fd[1],0,0); //解锁管道写端
exit(0); //子进程P2退出
}
//以下为主进程执行逻辑
wait(0); //等待某个子进程退出
if(r=read(fd[0],s,50)==-1) //从管道读端fd[0]读取P1或者P2写入的数据(视哪个子进程抢先执行到lockf函数)
{
printf(:can't read pipe\n"); //读取失败,打印错误信息
}
else
{
printf(:%s\n",s); //打印出读到的信息数据
}
wait(0); //等待第二个子进程退出
if(r=read(fd[0],s,50)==-1) //从管道读端fd[0]读取出P1或者P2写入的数据(视哪个子进程后执行到lockf函数)
{
printf(:can't read pipe\n"); //读取失败,打印错误信息
}
else
{
printf(:%s\n",s); //打印读取到的信息数据
}
exit(0); //主进程退出
}
}
总的说来,就是主进程创建了两个子进程P1、P2,这两个子进程分别向管道写入了一行文字,然后主进程从管道另一端将这两行文字读出并打印出来
由于进程的并发执行性,哪个子进程的信息先写到管道是随机的,因此该程序每次运行的输出可能并不相同,两行文字之间可能会相互交换
急!跳槽后户口和档案的问题(北京)
同情你,北漂一族。
我在广州漂, 也遇到类似的问题。好烦人的。 后来终于把户籍档案一起迁到广州了。
实验目的
1、进一步认识并发执行的实质
2、分析进程竞争资源的现象,学习解决进程互斥的方法
实验内容
1、修改实验(一)中的程序2,用lockf( )来给每一个进程加锁,以实现进程之间的互斥
2、观察并分析出现的现象
实验指导
一、所涉及的系统调用
lockf(files,function,size)
用作锁定文件的某些段或者整个文件。
本函数的头文件为
#include "unistd.h"
参数定义:
int lockf(files,function,size)
int files,function;
long size;
其中:files是文件描述符;function是锁定和解锁:1表示锁定,0表示解锁。size是锁定或解锁的字节数,为0,表示从文件的当前位置到文件尾。
二、参考程序
#include
#include
main( )
{
int p1,p2,i;
while((p1=fork( ))= = -1); /*创建子进程p1*/
if (p1= =0)
{
lockf(1,1,0); /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
for(i=0;i<10;i++)
printf("daughter %d\n",i);
lockf(1,0,0); /*解锁*/
}
else
{
while((p2=fork( ))= =-1); /*创建子进程p2*/
if (p2= =0)
{
lockf(1,1,0); /*加锁*/
for(i=0;i<10;i++)
printf("son %d\n",i);
lockf(1,0,0); /*解锁*/
}
else
{
lockf(1,1,0); /*加锁*/
for(i=0;i<10;i++)
printf(" parent %d\n",i);
lockf(1,0,0); /*解锁*/
}
}
}
三、运行结果
parent…
son…
daughter..
daughter..
或parent…
son…
parent…
daughter…
大致与未上锁的输出结果相同,也是随着执行时间不同,输出结果的顺序有所不同。
四、分析原因
上述程序执行时,不同进程之间不存在共享临界资源(其中打印机的互斥性已由操作系统保证)问题,所以加锁与不加锁效果相同。
五、分析以下程序的输出结果:
#include
#include
main()
{
int p1,p2,i;
int *fp;
fp = fopen("to_be_locked.txt"
,"w+");
if(fp==NULL)
{
printf("Fail to create file");
exit(-1);
}
while((p1=fork( ))== -1); /*创建子进程p1*/
if (p1==0)
{
lockf(*fp,1,0); /*加锁*/
for(i=0;i<10;i++)
fprintf(fp,"daughter %d\n",i);
lockf(*fp,0,0); /*解锁*/
}
else
{
while((p2=fork( ))==-1); /*创建子进程p2*/
if (p2==0)
{
lockf(*fp,1,0); /*加锁*/
for(i=0;i<10;i++)
fprintf(fp,"son %d\n",i);
lockf(*fp,0,0); /*解锁*/
}
else
{
wait(NULL);
lockf(*fp,1,0); /*加锁*/
for(i=0;i<10;i++)
fprintf(fp,"parent %d\n",i);
lockf(*fp,0,0); /*解锁*/
}
}
fclose(fp);
}
cat to_be_locked.txt 查看输出结果
你去你现在工作的北京公司所在的人才交流中心要求迁入你的档案,去派出所要求迁你的户口,并开具档案迁入接收证和户口准迁入证,得到这些证后,去你户口的所在地迁档案和户口迁移证。就行了。
请教windows 进程打开句柄个数的限制的问题
Perl flock()函数
语法
flock FILEHANDLE, OPERATION
定义和使用
支持文件锁定在指定的文件句柄,使用系统的flock(),fcntl()文件锁定,或使用lockf()。确切的实现是依赖于你的系统支持。操作是此处定义的静态值之一...
Operation Result LOCK_SH Set shared lock.
LOCK_EX Set exclusive lock.
LOCK_UN Unlock specified file.
LONG_NB Set lock without blocking.
返回值
0 设置/取消锁定失败时
iuni系统怎么把应用上锁
文件锁
1.fcntl()函数说明
前面讲述的5个基本函数实现了文件的打开、读/写等基本操作,本节将讨论在文件已经共享的情况下如何操作,也就是当多个用户共同使用、操作一个文件的情况。这时,Linux通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。
文件锁包括建议性锁和强制性锁。建议性锁要求每个上锁文件的进程都要检查是否有锁存在,并且尊重已有的锁。在一般情况下,内核和系统都不使用建议性锁。强制性锁是由内核执行的锁,当一个文件被上锁进行写入操作时,内核将阻止其他任何文件对其进行读写操作。采用强制性锁对性能的影响很大,每次读写操作都必须检查是否有锁存在。
在Linux中,实现文件上锁的函数有lockf()和fcntl(),其中lockf()用于对文件施加建议性锁,而fcntl()不仅可以施加建议性锁,还可以施加强制性锁。同时,fcntl()还能对文件的某一记录上锁,也就是记录锁。
记录锁又可分为读取锁和写入锁,其中读取锁又称为共享锁,它能够使多个进程都能在文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个进程在文件的某个部分建立写入锁。当然,在文件的同一部分不能同时建立读取锁和写入锁。
fcntl()函数具有很丰富的功能,它可以对已打开的文件描述符进行各种操作,不仅包括管理文件锁,还包括获得设置文件描述符和文件描述符标志、文件描述符的复制等很多功能。本节主要介绍fcntl()函数建立记录锁的方法,关于它的其他操作,感兴趣的读者可以参看fcntl手册。
2.fcntl()函数格式
用于建立记录锁的fcntl()函数语法要点如表2.6所示。
表2.6 fcntl()函数语法要点
所需头文件
#include
#include
#include
函数原型
int fcntl(int fd, int cmd, struct flock
*lock)
函数传入值
fd:文件描述符
cmd
F_DUPFD:复制文件描述符
F_GETFD:获得fd的close-on-exec标志,若标志未设置,则文件经过exec()函数之后仍保持打开状态
F_SETFD:设置close-on-exec标志,该标志由参数arg的FD_CLOEXEC位决定
F_GETFL:得到open设置的标志
F_SETFL:改变open设置的标志
F_GETLK:根据lock描述,决定是否上文件锁
F_SETLK:设置lock描述的文件锁
F_SETLKW:这是F_SETLK的阻塞版本(命令名中的W表示等待(wait))。
在无法获取锁时,会进入睡眠状态;如果可以获取锁或者捕捉到信号则会返回
lock:结构为flock,设置记录锁的具体状态,后面会详细说明
函数返回值
成功:0
1:出错
这里,lock的结构如下所示:
struct flock
{
short
l_type;
off_t l_start;
short l_whence;
off_t
l_len;
pid_t l_pid;
}
lock结构中每个变量的取值含义如表2.7所示。
表2.7 lock结构变量取值
l_type
F_RDLCK:读取锁(共享锁)
F_WRLCK:写入锁(排斥锁)
F_UNLCK:解锁
l_start
加锁区域在文件中的相对位移量(字节),与l_whence值一起决定加锁区域的起始位置
l_whence:
相对位移量的起点(同lseek的whence)
SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小
SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量
SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小
l_len
加锁区域的长度
为加锁整个文件,通常的方法是将l_start设置为0,l_whence设置为SEEK_SET,l_len设置为0。
3.fcntl()使用实例
下面首先给出了使用fcntl()函数的文件记录锁功能的代码实现。在该代码中,首先给flock结构体的对应位赋予相应的值。
接着调用两次fcntl()函数。用F_GETLK命令判断是否可以进行flock结构所描述的锁操作:若可以进行,则flock结构的l_type会被设置为F_UNLCK,其他域不变;若不可进行,则l_pid被设置为拥有文件锁的进程号,其他域不变。
用F_SETLK和F_SETLKW命令设置flock结构所描述的锁操作,后者是前者的阻塞版。
当第一次调用fcntl()时,使用F_GETLK命令获得当前文件被上锁的情况,由此可以判断能不能进行上锁操作;当第二次调用fcntl()时,使用F_SETLKW命令对指定文件进行上锁/解锁操作。因为F_SETLKW命令是阻塞式操作,所以,当不能把上锁/解锁操作进行下去时,运行会被阻塞,直到能够进行操作为止。
文件记录锁的功能代码具体如下所示:
/* lock_set.c */
int lock_set(int
fd, int type)
{
struct flock old_lock,
lock;
lock.l_whence = SEEK_SET;
lock.l_start =
0;
lock.l_len = 0;
lock.l_type =
type;
lock.l_pid = -1;
/* 判断文件是否可以上锁
*/
fcntl(fd, F_GETLK, &lock);
if (lock.l_type !=
F_UNLCK)
{
/* 判断文件不能上锁的原因 */
if
(lock.l_type == F_RDLCK) /* 该文件已有读取锁
*/
{
printf("Read lock already set by %d\n",
lock.l_pid);
}
else if (lock.l_type == F_WRLCK) /*
该文件已有写入锁 */
{
printf("Write lock already set
by %d\n", lock.l_pid);
}
}
/* l_type
可能已被F_GETLK修改过 */
lock.l_type = type;
/*
根据不同的type值进行阻塞式上锁或解锁 */
if ((fcntl(fd, F_SETLKW, &lock)) <
0)
{
printf("Lock failed:type = %d\n",
lock.l_type);
return
1;
}
switch(lock.l_type)
{
case
F_RDLCK:
{
printf("Read lock set by %d\n",
getpid());
}
break;
case
F_WRLCK:
{
printf("Write lock set by %d\n",
getpid());
}
break;
case
F_UNLCK:
{
printf("Release lock by %d\n",
getpid());
return
1;
}
break;
default:
break;
}/*
end of switch */
return 0;
}
下面的实例是文件写入锁的测试用例,这里首先创建了一个hello文件,之后对其上写入锁,最后释放写入锁。代码如下所示:
/* write_lock.c */
#include
#include
#include
#include
#include
#include
#include
"lock_set.c"
int main(void)
{
int
fd;
/* 首先打开文件 */
fd = open("hello",O_RDWR | O_CREAT,
0644);
if(fd < 0)
{
printf("Open file
error\n");
exit(1);
}
/* 给文件上写入锁
*/
lock_set(fd, F_WRLCK);
getchar();
/* 给文件解锁
*/
lock_set(fd, F_UNLCK);
getchar();
close(fd);
exit(0);
}
为了能够使用多个终端,更好地显示写入锁的作用,本实例主要在PC上测试,读者可将其交叉编译,下载到目标板上运行。下面是在PC上的运行结果。为了使程序有较大的灵活性,笔者采用文件上锁后由用户输入任意键使程序继续运行。建议读者开启两个终端,并且在两个终端上同时运行该程序,以达到多个进程操作一个文件的效果。在这里,笔者首先运行终端一,请读者注意终端二中的第一句。
终端一:
$ ./write_lock
write lock set by
4994
release lock by 4994
终端二:
$ ./write_lock
write lock already
set by 4994
write lock set by 4997
release lock by 4997
由此可见,写入锁为互斥锁,同一时刻只能有一个写入锁存在。
接下来的程序是文件读取锁的测试用例,原理与上面的程序一样。
/* fcntl_read.c */
#include
#include
#include
#include
#include
#include
#include
"lock_set.c"
int main(void)
{
int fd;
fd
= open("hello",O_RDWR | O_CREAT, 0644);
if(fd <
0)
{
printf("Open file
error\n");
exit(1);
}
/* 给文件上读取锁
*/
lock_set(fd, F_RDLCK);
getchar();
/* 给文件解锁
*/
lock_set(fd, F_UNLCK);
getchar();
close(fd);
exit(0);
}
同样开启两个终端,并首先启动终端一上的程序,其运行结果如下所示。
终端一:
$ ./read_lock
read lock set by
5009
release lock by 5009
终端二:
$ ./read_lock
read lock set by
5010
release lock by 5010
读者可以将此结果与写入锁的运行结果相比较,可以看出,读取锁为共享锁,当进程5009已设置读取锁后,进程5010仍然可以设置读取锁。
在C语言中,怎么对一个fopen打开的FILE文件加锁啊?防止同时被读写,不要LINUX的方法
是在windows下? 用 LockFile或LockFileEx
参见MSDN.
file lock并不是C库自带的功能,与系统有关系的
用下面的其中一个函数:
flock();
lockf();
fcntl();