LinuxSir.cn,穿越时空的Linuxsir!

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

在Linux中程序如何感知某个程序正在运行呢?还有禁止自己重载?

[复制链接]
发表于 2003-5-7 10:09:54 | 显示全部楼层
按照kj501说的就可以了,这也是现在比较常用的办法
发表于 2003-5-7 15:40:55 | 显示全部楼层
我以前的一段代码,参考UNIX高级编程12章记录锁,其实基本上就是照搬的。建议你好好看看这本书吧。
原理就是打开一个文件,然后锁定,新运行的程序会试图再次锁定该文件,但是因为已经被锁定,所以会返回错误信息。据此就可以判断是否有程序已经运行。设置FD_CLOEXEC后,只要程序终止,都可以再次锁定。
通常精灵进程都使用这种方法,比如apache等等,而且默认都会在/var/run目录下。


//保证系统中只有一个程序实例
#define PIDFILE         "/var/run/my.pid"
#define write_lock(fd,offset,whence,len)        lock_reg(fd,F_SETLK,F_WRLCK,offset,whence,len)



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));
}



void setpid()
{

        int     fd,val;
        char    buf[10];

        if ((fd=open(PIDFILE,O_WRONLY|O_CREAT,FILE_MODE))<0)
                syslog(LOG_ERR,strerror(errno));
        if(write_lock(fd,0,SEEK_SET,0) < 0)
        {
                printf("&sup3;&Igrave;&ETH;ò&Ograve;&Ntilde;&frac34;&shy;&Ocirc;&Euml;&ETH;&ETH;&pound;&iexcl;\n");
                if (errno == EACCES || errno == EAGAIN)
                        syslog(LOG_ERR,"LCD Control has been in running! ");
                else
                        syslog(LOG_ERR,strerror(errno));
                exit(0);
        }
        syslog(LOG_ERR,"LCD Control start success. ");

        if (ftruncate(fd,0) <0)
                syslog(LOG_ERR,strerror(errno));
        sprintf(buf,"%d\n",getpid());
        if (write(fd,buf,strlen(buf))!=strlen(buf))
                printf("write error");

        if  ((val = fcntl(fd,F_GETFD,0))<0)
                printf("fcntl F_GETFD error");
        val |= FD_CLOEXEC;
        if (fcntl(fd,F_SETFD,val)<0)
                printf("fcntl F_SETFD error");
        return;

}
 楼主| 发表于 2003-5-8 19:23:45 | 显示全部楼层
编译通不过啊!错太多了?
发表于 2003-5-9 16:59:27 | 显示全部楼层
man一下那几个不常用的函数,你包含的头文件不够吧?
或者把错贴出来啊。
 楼主| 发表于 2003-5-13 14:02:37 | 显示全部楼层

以下是我的程序代码

参考UNIX高级编程12章记录锁后,还是不行啊!
请tedyt指点,以下是我的程序代码.h与.C文件,编译时有很多错.
ourhdr.h文件
/* Our own header, to be included *after* all standard system headers */
#ifndef  __ourhdr h
#define  __ourhdr h

#include <sys/types.h>    /* required for some of our prototypes */
#include <stdio.h>         /* for convenience */
#include <stdlib.h>        /* for convenience */
#include <string.h>        /* for convenience */
#include <unistd.h>        /* for convenience */
#define MAXLINE 4096               /* max line length */
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
                  /* default file access permissions for new files */
#define DIR_MODE  (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
                  /* default permissions for new directories */
typedef void Sigfunc(int);    /* for signal handlers */
                                       /* 4.3BSD Reno <signal.h> doesn't define SIG ERR */
#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR((Sigfunc *)-1)
#endif

#define min(a,b)  ((a) < (b) ? (a) : (b))
#define max(a,b)  ((a) > (b) ? (a) : (b))
                                       /* prototypes for our own functions */
char *path_alloc(int *);            /* Program 2.2 */
iht   open_max(void);                /* Program 2.3 */
void  clr_fl(int,  int);             /* Program 3.5 */
void  set_fl(int, int);            /* Program 3.5 */
void  pr_exit(int);                  /* Program 8.3 */
void  pr_mask(const char *);       /* Program 10.10 */
Sigfunc *signal_intr(int, Sigfunc *);/* Program 10.13 */

int tty_cbreak(int);              /* Program 11.10 */
int tty_raw(int);                  /* Program 11.10 */
int tty_reset(int);                /* Program 11.10 */
void  tty_atexit(void);             /* Program 11.10 */
#ifdef  ECHO     /* only if <termios.h> has been included */
struct termios  *tty_termios(void);  /* Program 11.10 */
#endif

void     sleep_us(unsigned int);     /* Exercise 12.6 */
ssize_t  readn(int, void *,  size_t);/* Program 12.13 */
ssize_t  writen(int, const void *, size_t);/* Program 12.12 */
int daemon_init(void);            /* Program 13.1 */
int s_pipe(int *);                 /* Programs 15.2 and 15.3 */
int recv_fd(int,ssize_t (*func) (int,const void *,size_t));
                                                                      /* Programs 15.6 and 15.8 */
int send_fd(int,int);            /* Programs 15.5 and 15.7 */
int send_err(int,int,const char *);/* Program 15.4 */
int serv_listen(const char *);  /* Programs 15.19 and 15.22 */
int serv_accept(int,uid t *);  /* Programs 15.20 and 15.24 */
int cli_conn(const char *);     /* Programs 15.21 and 15.23 */
int buf_args(char *,int (*func) (int, char **));
                                                                      /* Program 15.17 */
int ptym_open(char *);            /* Programs 19.1 and 19.2 */
int ptys_open(int,char *);     /* Programs 19.1 and 19.2 */
#ifdef TIOCGWINSZ
pid_t pty_fork(int *,char *,const struct termios *,const struct winsize *);   /* Program 19.3 */
#endif
int lock_reg(int,int,int,off_t,int,off_t);
                                                                  /* Program 12.2 */
#define read_lock(fd,offset,whence,len)  \
                       lock_reg(fd,F_SETLK,F_RDLCK,offset,whence,len)

#define readw_lock(fd,offset,whence,len)  \
                       lock_reg(fd,F_SETLKW,F_RDLCK,offset,whence,len)

#define write lock(fd,offset,whence,len)  \
                       lock_reg(fd,F_SETLK,F_WRLCK,offset,whence,len)

#define writew_lock(fd,offset,whence,len)  \
                       lock_reg(fd,F_SETLKW,F_WRLCK,offset,whence,len)

#define un_lock(fd,offset,whence,len) \
                       lock_reg(fd,F_SETLK,F_UNLCK,offset,whence,len)
pid_t lock_test(int,int,off_t,int,off_t);
                                                                  /* Program 12.3 */
#define is_readlock(fd,offset,whence,len)  \
                       lock test(fd,F__RDLCK,offset,whence,len)

#define is_writeTock(fd,offset,whence,len)  \
                       lock_test(fd, F_WRLCK,  offset, whence,  len)

void  err_dump(const char *,  ...);     /* Appendix B */
void  err_msg(const char *,  ...);
void  err_quit(const char *,  ...);
void  err_ret(const char *,  ...);
void  err_sys(const char *,  ...);
void  log_msg(const char *,  ...);       /* Appendix B */
void  log_open(const char *,int,int);
void  log_quit(const char *,  ...);
void  log_ret(const char *,  ...);
void  lcg_sys(ccnst char *  ....  );

void  TELL_WAIT(void);           /* parent/child from Section 8.8 */
void  TELL_PARENT(pid_t);
void  TELL_CHILD(pidt);
void  WAIT PARENT{void);
void  WAIT_CHILD(void);

#endif  /*    ourhdr h */


以下是Lock.c 文件

#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)
     printf/*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
         printf/*err_sys*/("write_lock error");
  }
  /* truncate to zero length, now that we have the lock */
  if(ftruncate(fd, 0) < 0)
     printf/*err_sys*/("ftruncate error");
       /* and write our process ID */
  sprintf(buf, "%d\n", getpid());
  if (write(fd, buf, strlen(buf))  != strlen(buf))
      printf/*err_sys*/("write error");
       /* set close-on-exec flag for descriptor */
  if ( (val = fcntl(fd, F_GETFD, 0)) < 0)
      printf/*err_sys*/("fcntl F_GETFD error");
  val |= FD_CLOEXEC;
  if (fcntl(fd, F_SETFD, val) < 0)
      printf/*err_sys*/("fcntl F_SETFD error");
/* leave file open until we terminate: lock will be held */
/* do whatever ...  */
  exit (0);
}
发表于 2003-5-13 16:15:56 | 显示全部楼层

I 服了 U

大哥,你的代码里面声明了int lock_reg(int,int,int,off_t,int,off_t);
可是函数的实现在那里啊?我贴出来的贴子里就有实现函数啊。

还有诸多的拼写错误,我不知道是贴上时出错了还是什么?
如果是你自己的错误,请以后看仔细些。
如果你对C语言还不了解,还是先学习的好,不要一味的抄代码,有什么用呢?
 楼主| 发表于 2003-5-14 09:04:23 | 显示全部楼层
多谢tedyt啦!
贴出的代码是从UNIX高级编程12章中用尚书6号识别出来的,
现在已改好了,多谢啦!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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