LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: tigeroar

怎么让一个程序在同一时间只有一个进程运行?

[复制链接]
发表于 2005-11-2 12:35:29 | 显示全部楼层
不过还有一点,记录锁不是数据库里的么?程序中也可以用?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-2 14:39:29 | 显示全部楼层
锁文件是不是在root用户下就失效了?
回复 支持 反对

使用道具 举报

发表于 2005-11-2 15:16:12 | 显示全部楼层
看书去吧
apue里还有个简单的数据库的实现
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-3 09:36:12 | 显示全部楼层
看到一个精灵程序,不过是只能运行一次的程序。
回复 支持 反对

使用道具 举报

发表于 2005-11-3 21:12:26 | 显示全部楼层
在置顶中找到的:
2.5 我如何锁住一个文件?
========================
有三种不同的文件锁,这三种都是“咨询性”的,也就是说它们依靠程序之间的
合作,所以一个项目中的所有程序封锁政策的一致是非常重要的,当你的程序需
要和第三方软件共享文件时应该格外地小心。

有些程序利用诸如 FIlENAME.lock 的文件锁文件,然后简单地测试此类文件是否
存在。这种方法显然不太好,因为当产生文件的进程被杀后,锁文件依然存在,
这样文件也许会被永久锁住。UUCP中把产生文件的进程号PID存入文件,但这样做
仍然不保险,因为PID的利用是回收型的。

这里是三个文件锁函数:
flock();
lockf();
fcntl();

flock()是从BSD中衍生出来的,但目前在大多数UNIX系统上都能找到,在单个主
机上flock()简单有效,但它不能在NFS上工作。Perl中也有一个有点让人迷惑的
flock()函数,但却是在perl内部实现的。

fcntl()是唯一的符合POSIX标准的文件锁实现,所以也是唯一可移植的。它也同
时是最强大的文件锁——也是最难用的。在NFS文件系统上,fcntl()请求会被递
交给叫rpc.lockd的守护进程,然后由它负责和主机端的lockd对话,和flock()
不同,fcntl()可以实现记录层上的封锁。

lockf()只是一个简化了的fcntl()文件锁接口。

无论你使用哪一种文件锁,请一定记住在锁生效之前用sync来更新你所有的文件
输入/输出。

lock(fd);
write_to(some_function_of(fd));
flush_output_to(fd); /* 在去锁之前一定要冲洗输出 */
unlock(fd);
do_something_else; /* 也许另外一个进程会更新它 */
lock(fd);
seek(fd, somewhere); /* 因为原来的文件指针已不安全 */
do_something_with(fd);
...

一些有用的fcntl()封锁方法(为了简洁略去错误处理):


#include <fcntl.h>
#include <unistd.h>

read_lock(int fd) /* 整个文件上的一个共享的文件锁 */
{
fcntl(fd, F_SETLKW, file_lock(F_RDLCK, SEEK_SET));
}

write_lock(int fd) /* 整个文件上的一个排外文件锁 */
{
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
}

append_lock(int fd) /* 一个封锁文件结尾的锁,
其他进程可以访问现有内容 */
{
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_END));
}

前面所用的file_lock函数如下:

struct flock* file_lock(short type, short whence)
{
static struct flock ret ;
ret.l_type = type ;
ret.l_start = 0 ;
ret.l_whence = whence ;
ret.l_len = 0 ;
ret.l_pid = getpid() ;
return &ret ;
}
回复 支持 反对

使用道具 举报

发表于 2005-11-4 08:27:19 | 显示全部楼层
...简单化处理: 程序通过脚本启动, 在脚本里检测当前进程表  如果有发现已经启动的目标进程 那就退出...
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-4 09:47:48 | 显示全部楼层
楼上的也是一种方法,我是看着apaue来做的贴出来,大家给找找问题.

//tigeroar.org
//2005-10-8

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <time.h>



using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////
//tigeroar
//2005-11-3

#define write_lock(fd,offset,whence,len) \
lock_reg(fd,F_SETLK,F_WRLCK,offset,whence,len)
#define un_lock(fd,offset,whence,len) \
lock_reg(fd,F_SETLK,F_UNLCK,offset,whence,len)
#define PIDFILE "daemon.pid"

int lock_reg(int fd,int cmd,int type,off_t offset,int whence,off_t len);




int main(int argc, char *argv[])
{
        int lockfd;
        char buf[16];
       

        if((lockfd = open(PIDFILE,O_WRONLY|O_CREAT))<0)
        {
                printf("open error\n");
                perror("open :\n");
        }
        if(write_lock(lockfd,0,SEEK_END,0)<0)
        {
                if(errno==EACCES||errno==EAGAIN)
                        exit(0);
                else
                        printf("write_lock error\n");
        }

        if(ftruncate(lockfd,0)<0)
                syslog(LOG_ERR,"ftruncate error\n");
        sprintf(buf,"%d\n",getpid());
        if(write(lockfd,buf,strlen(buf))!=strlen(buf))
                syslog(LOG_ERR,"write pid error\n");
       

       
        un_lock(lockfd,0,SEEK_SET,0);
        close(lockfd);

        return EXIT_SUCCESS;
}


int lock_reg(int fd,int cmd,int type,off_t offset,int whence,off_t len)
{
        struct flock lock;
        lock.l_type = type;
        lock.l_start = offset;
        lock.l_whence = whence;
        lock.l_len = len;
       
        return(fcntl(fd,cmd,&lock));
}
回复 支持 反对

使用道具 举报

发表于 2005-11-4 11:15:44 | 显示全部楼层
Post by zhllg
看书去吧
apue里还有个简单的数据库的实现

一大早出发,买了本apue回来!!!!!11
回复 支持 反对

使用道具 举报

发表于 2005-11-4 14:03:56 | 显示全部楼层
还有就是记录一下PID,程序起动的时候如果没有有这个包含PID的文件,说明没有起动
如果有,再在/proc/PID/目录下看看cmdline这个文件,是不是你的程序,是表示起动,不是就表示没有起动
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表