免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 9004 | 回复: 13
打印 上一主题 下一主题

如何只让我的程序只运行一个实例? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-12-15 11:17 |只看该作者 |倒序浏览
我是一个unix/linux下c语言的新丁(主要是实作做得少)
我写了一个程序,程序中有我没有找出的bug,偶尔会导致程序退出,于是我写了一个脚本(用grep 来查)每5秒来查一次是否正在运行,否则再把那个程序跑起来,结果呢,这个脚本往往坏事,我有时会看到有好几个我的程序在跑,真是郁闷。
有什么办法让我只运行一个实例呢?
当然找出bug是必要的,但并不那么容易。

论坛徽章:
0
2 [报告]
发表于 2004-12-15 11:29 |只看该作者

如何只让我的程序只运行一个实例?

最简单的,创建一个配置文件启动修改计数器,下个副本启动的时候检测计数器,大与1exit;缺点:程序退出没修改计数器,就没办法了。
偶知道windows下创建一个互斥就好了,linux下不知道用什么。

论坛徽章:
0
3 [报告]
发表于 2004-12-15 11:43 |只看该作者

如何只让我的程序只运行一个实例?

约定一个文件,进程运行时检测、锁定该文件。

论坛徽章:
0
4 [报告]
发表于 2004-12-15 11:51 |只看该作者

如何只让我的程序只运行一个实例?

嗯,同意楼上老大说的,unix中经常可以看到.lock的空文件,就是干这个的

论坛徽章:
0
5 [报告]
发表于 2004-12-15 11:55 |只看该作者

如何只让我的程序只运行一个实例?

关键问题是我的程序退出是非正常退出,如果锁定了一个文件,系统会不会自动解锁呢?
谢谢。

论坛徽章:
0
6 [报告]
发表于 2004-12-15 12:31 |只看该作者

如何只让我的程序只运行一个实例?

退出时会释放文件锁

论坛徽章:
0
7 [报告]
发表于 2004-12-15 15:26 |只看该作者

如何只让我的程序只运行一个实例?

1.为什么不从根本上解决,?可以用很多的工具来调试你的程序。
2.你的shell 肯定写的有问题

论坛徽章:
0
8 [报告]
发表于 2004-12-15 19:08 |只看该作者

如何只让我的程序只运行一个实例?

谢谢。
正准备去写代码先测试一下。
to lacmd:
1.shell脚本确实有问题,我用ps -ef |grep xxx |grep -v grep来查的
确实出现好几次明明存在程序xxx在运行,却没有找出来,所以导致脚本会运行另一个实例,所以今天修改了一下script,没有出现那样的现象了
2.bug这个东西就不好说了,一般来而言,任何程序都会有bug---并不是为自己找借口,这个bug我查了好久了,没有太多头绪--因为是偶尔才发生的--,此外,这个程序因为业务的需要必须时刻要跑,所以不得不先弄一个script来监视着。
无论如何,谢谢参与。

论坛徽章:
0
9 [报告]
发表于 2004-12-15 22:27 |只看该作者

如何只让我的程序只运行一个实例?

终于弄好了。
晚上回家,翻书看到apue(unix 环境高级编程)12-5,就是我所需要的。
经过测试,就是我所需要的。所用的方法同上面的朋友说的差不多
----我本来打算用信号量的,查了一下书,还是有点复杂。
谢谢所有回复的朋友。

抄来的代码如下:

  1. #include        <sys/stat.h>;
  2. #include        <errno.h>;
  3. #include        <fcntl.h>;
  4. #include        <sys/types.h>;
  5. #include        <fcntl.h>;
  6. #define PIDFILE "pid-s2mail.pid"
  7. #define        FILE_MODE        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

  8. int
  9. lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
  10. {
  11.         struct flock        lock;
  12.        
  13.         lock.l_type = type;                /* F_RDLCK, F_WRLCK, F_UNLCK */
  14.         lock.l_start = offset;        /* byte offset, relative to l_whence */
  15.         lock.l_whence = whence;        /* SEEK_SET, SEEK_CUR, SEEK_END */
  16.         lock.l_len = len;                /* #bytes (0 means to EOF) */
  17.        
  18.         return( fcntl(fd, cmd, &lock) );
  19. }

  20. #define        read_lock(fd, offset, whence, len) \
  21. lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)
  22. #define        readw_lock(fd, offset, whence, len) \
  23. lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len)
  24. #define        write_lock(fd, offset, whence, len) \
  25. lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)
  26. #define        writew_lock(fd, offset, whence, len) \
  27. lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)
  28. #define        un_lock(fd, offset, whence, len) \
  29. lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)




  30. void err_sys(char * str)
  31. {
  32.         printf("%s\n",str);
  33.         exit(-2);
  34. }
  35. int check_running()
  36. {
  37.         int                fd, val;
  38.         char        buf[10];
  39.        
  40.         if ( (fd = open(PIDFILE, O_WRONLY | O_CREAT, FILE_MODE)) < 0)
  41.                 err_sys("open file error\n");
  42.        
  43.                         /* try and set a write lock on the entire file */
  44.         if (write_lock(fd, 0, SEEK_SET, 0) < 0)        {
  45.                 if (errno == EACCES || errno == EAGAIN)
  46.                         exit(0);        /* gracefully exit, daemon is already running */
  47.                 else
  48.                         err_sys("write_lock error");
  49.         }
  50.        
  51.                         /* truncate to zero length, now that we have the lock */
  52.         if (ftruncate(fd, 0) < 0)
  53.                 err_sys("ftruncate error");
  54.        
  55.                         /* and write our process ID */
  56.         sprintf(buf, "%d\n", getpid());
  57.         if (write(fd, buf, strlen(buf)) != strlen(buf))
  58.                 err_sys("write error");
  59.        
  60.                         /* set close-on-exec flag for descriptor */
  61.         if ( (val = fcntl(fd, F_GETFD, 0)) < 0)
  62.                 err_sys("fcntl F_GETFD error");
  63.         val |= FD_CLOEXEC;
  64.         if (fcntl(fd, F_SETFD, val) < 0)
  65.                 err_sys("fcntl F_SETFD error");

  66.         return 0;
  67. }
复制代码

论坛徽章:
0
10 [报告]
发表于 2004-12-16 10:09 |只看该作者

如何只让我的程序只运行一个实例?

程序运行时把processid写入一个文件xxx.pid中,
每次启动时检测xxx.pid是否为空,为空咋程序继续执行,并把processid写入xxx.pid,不空咋异常退出。
脚本启动程序时,必须先把xxx.pid清空,才能把程序启动起来,这样子就能保证唯一了。很多open source的项目,如jabber的server程序第二次启动时要先把xxx.pid手动清空才能启动起来 。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP