Chinaunix

标题: 关于文件锁的问题 [打印本页]

作者: elechi    时间: 2005-12-20 13:33
标题: 关于文件锁的问题
一个进程打开一个文件,并在其上设置了一把锁,同时打开此文件的执行时关闭标志,那么此进程在fork,exec之后,文件上面的锁还存在吗?
作者: lenovo    时间: 2005-12-20 15:27
>>打开此文件的执行时关闭标志
这个都打开了,
文件都关闭了,
哪里还有锁呀?
作者: elechi    时间: 2005-12-20 16:18
我也同意楼上的,但是APUE的程序12-5,精灵进程利用文件锁阻止多分副本同时运行的代码中,如果按楼上的观点的话,岂不是达不到程序的目的了,还是我没看懂代码?请指教,源码如下:
:
#include        <sys/types.h>
#include        <sys/stat.h>
#include        <errno.h>
#include        <fcntl.h>
#include        "ourhdr.h"

#define        PIDFILE                "daemon.pid"

int
main(void)
{
        int                fd, val;
        char        buf[10];

        if ( (fd = open(PIDFILE, O_WRONLY | O_CREAT, FILE_MODE)) < 0)
                err_sys("open error");

                        /* try and set a write lock on the entire file */
        if (write_lock(fd, 0, SEEK_SET, 0) < 0)        {
                if (errno == EACCES || errno == EAGAIN)
                        exit(0);        /* gracefully exit, daemon is already running */
                else
                        err_sys("write_lock error");
        }

                        /* truncate to zero length, now that we have the lock */
        if (ftruncate(fd, 0) < 0)
                err_sys("ftruncate error");

                        /* and write our process ID */
        sprintf(buf, "%d\n", getpid());
        if (write(fd, buf, strlen(buf)) != strlen(buf))
                err_sys("write error");

                        /* set close-on-exec flag for descriptor */
        if ( (val = fcntl(fd, F_GETFD, 0)) < 0)
                err_sys("fcntl F_GETFD error");
        val |= FD_CLOEXEC;
        if (fcntl(fd, F_SETFD, val) < 0)
                err_sys("fcntl F_SETFD error");

        /* leave file open until we terminate: lock will be held */

        /* do whatever ... */
        /*如果在这里exec的话,文件锁还在吗?*/

        exit(0);
}
作者: ivhb    时间: 2005-12-20 17:08
因为精灵进程启动后不会占用终端,你会觉得它好像立刻就结束了。
为了防止你再启动该程序(同时运行一个程序两遍)。
而不是说可以防止你代码中fork, exec同时启动两个进程。
不知道我说明白没有:)
作者: elechi    时间: 2005-12-20 17:35
楼上的你没看明白吧,那个程序的目的就是防止同一个程序起动两次.
我的问题重点不是精灵进程,是exec后文件锁还在吗?

我刚才在上面的程序/* do whatever ... */后加了两行代码,
if(system("date")<0)
                err_sys("error");
sleep(10);

执行上面的代码后,此程序仍不能启动两次,也就是说文件锁依然存在,我估计是exec后通过执行关闭位关闭的文件,文件锁不释放.
作者: ivhb    时间: 2005-12-20 17:57
问题是system()并不会关闭以前打开的文件描述符
不信你自己试试看好了
作者: lenovo    时间: 2005-12-20 18:05
比如你的deamon进程启动了,
然后它fork并exec了一个子进程,
设置了执行时关闭标志后,
这个文件就不会在子进程中打开。
这不是很好理解吗?
子进程要打开这个文件干嘛?
只需要deamon进程打开就可以了。
你需要仔细看书。
作者: elechi    时间: 2005-12-20 18:06
我又迷糊了,我现在把/* do whatever ... */后的代码修改如下:
if((pid=fork())<0)
                err_sys("error");
        else if(pid==0){
                close(fd);
                exit(0);
        }       
if(pid!=wait())
        err_sys("error");
printf("in sleep\n");
       
sleep(10);
printf("sleep end");

程序仍然不能运行两次,也就是说我直接调用close后,文件锁还在,

我做了些实验,感觉应该是这样的.关闭一个文件时,只释放此此调用进程所设置的锁,不知对否?
作者: elechi    时间: 2005-12-20 18:09
原帖由 lenovo 于 2005-12-20 18:05 发表
比如你的deamon进程启动了,
然后它fork并exec了一个子进程,
设置了执行时关闭标志后,
这个文件就不会在子进程中打开。
这不是很好理解吗?
子进程要打开这个文件干嘛?
只需要deamon进程打开就可以了。
...

子进程默认是继承父进程的所有打开的文件描述符的.
作者: lenovo    时间: 2005-12-20 18:10
我倒,你不是已经用了执行时关闭标志吗?
它还怎么继承呀?!
作者: lenovo    时间: 2005-12-20 18:12
原帖由 elechi 于 2005-12-20 18:06 发表
我又迷糊了,我现在把/* do whatever ... */后的代码修改如下:
if((pid=fork())<0)
                err_sys("error");
        else if(pid==0){
                close(fd);
                exit(0);
        }       
if(pid!=wait())
        err_sys("er ...

子进程关闭了,
父进程还没有关闭呀。
同意你的观点。
作者: ivhb    时间: 2005-12-20 19:05
我做了些实验,感觉应该是这样的.关闭一个文件时,只释放此此调用进程所设置的锁,不知对否?
//
呵呵,肯定是这样的。 否则, A用户的某个用户进程占了一个文件, 岂不是其他用户(或者本用户)的其他进程不能得到可靠的锁?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2