免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: spiritX

Unix下有什么方法实现防止程序多重执行? [复制链接]

论坛徽章:
0
发表于 2009-02-05 15:43 |显示全部楼层
原帖由 spiritX 于 2009-2-5 15:41 发表


指导一下这分就给你了

关键是我不知道你好哪口啊,信号量,消息队列。。。。

论坛徽章:
0
发表于 2009-02-05 15:47 |显示全部楼层
原帖由 alexhappy 于 2009-2-5 15:43 发表

关键是我不知道你好哪口啊,信号量,消息队列。。。。


消息队列这个搞大了, 应该不需要吧.

solaris下有个mutex_init, 但是着玩意没有参数建立有名的内核对象啊.

int mutex_init(mutex_t *mp, int type, void * arg);

int mutex_lock(mutex_t *mp);

int mutex_trylock(mutex_t *mp);

int mutex_unlock(mutex_t *mp);

int mutex_destroy(mutex_t *mp);

论坛徽章:
0
发表于 2009-02-05 16:16 |显示全部楼层
用进行的PID进行防止二重启动的控制
(1)定一个放置本程序执行的PID的文件
  char PID_FILE[255] = "APP.PID";
(2)如果APP.PID文件不存在,则本程序没有运行,创建该文件,并把当前运行程序的PID写入该文件
  pid_t pid = -1;
  pid = getpid();
  /* 把pid写入APP.PID文件 */
  /* 执行程序的功能 */
执行(4)
(3)如果APP.PID文件存在,则从APP.PID文件中读取PID值和系统进程表中正在运行进程的PID进行比较,
  [
  /* 从APP.PID文件中读取PID值,放到PID_Value中 */
  strcpy(PS_CMD, "ps -ef|awk '{print $2}'|grep ");
  strcat(PS_CMD, PID_Value);
  /* 在进程表中查找PID_Value值 */
  if((fd = popen(PS_CMD, "r")) == NULL) {
  printf("call popen failed\n");
  return;
  } else {
  while(fgets(str, 255, fd) != NULL) {
  printf("%s\n",str);
  bRun = 1;
  break;
  }
  }
  ]
  如果在进程表中不存在,则表示本程序未被运行,执行(2);
  如果在进程表中存在,则执行(4)
(4)退出程序。

论坛徽章:
0
发表于 2009-02-05 16:36 |显示全部楼层
原帖由 spiritX 于 2009-2-5 15:47 发表


消息队列这个搞大了, 应该不需要吧.

solaris下有个mutex_init, 但是着玩意没有参数建立有名的内核对象啊.

int mutex_init(mutex_t *mp, int type, void * arg);

int mutex_lock(mutex_t *mp);

...

为嘛不用文件呢?最简单就是根据参数组合创建一个文件,然后unlink它。这样既可以保证一种参数只有一个进程在执行,而又不会遗留文件。因为就算OS崩溃了也没问题,unlink的文件也会被自动删除的。
char argfile[256];
argfile[0] = 0;
strcat(argfile, "~/");
for(int i = 0; i < argc; ++i)
    strcat(argfile, argv[i]);
//... Populate flags
int err = open(argfile, flags);
if (err> 0)
    unlink(argfile);
else
    exit;

经测试可用的例子——无论进程崩溃、被杀,还是系统崩溃都不会遗留文件,而且只允许启动一份
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    char* filename = "./.hello";
    int err;
    if ((err = open(filename, O_CREAT|O_RDONLY)) != -1)
    {
        unlink(filename);
        while (1);
    }
    else
    {
        perror("ERROR");
        printf("%d\n", err);
        exit(err);
    }
}


#include <unistd.h>

int unlink(const char *pathname);
Description
unlink() deletes a name from the filesystem. If that name was the last link to a file and no processes have the file open the file is deleted and the space it was using is made available for reuse.

If the name was the last link to a file but any processes still have the file open the file will remain in existence until the last file descriptor referring to it is closed.

If the name referred to a symbolic link the link is removed.

If the name referred to a socket, fifo or device the name for it is removed but processes which have the object open may continue to use it.

[ 本帖最后由 fera 于 2009-2-5 17:25 编辑 ]

论坛徽章:
0
发表于 2009-02-05 16:40 |显示全部楼层
总的来说,就是设计一个标志,表示程序已经启动

比如文件锁、记录PID等等方法,都是很有效的方法

论坛徽章:
0
发表于 2009-02-05 16:42 |显示全部楼层
原帖由 nicksean 于 2009-2-5 16:16 发表
用进行的PID进行防止二重启动的控制
(1)定一个放置本程序执行的PID的文件
  char PID_FILE[255] = "APP.PID";
(2)如果APP.PID文件不存在,则本程序没有运行,创建该文件,并把当前运行程序的PID写入该文 ...

你这种方法是用来保证系统中只有一个进程在执行该程序。

论坛徽章:
0
发表于 2009-02-05 16:54 |显示全部楼层
原帖由 fera 于 2009-2-5 16:36 发表

为嘛不用文件呢?最简单就是根据参数创建一个文件,然后unlink它。这样就算OS崩溃了也没问题,它会被自动删除的。

unlink后别的进程可以再打开它吗?

论坛徽章:
0
发表于 2009-02-05 16:58 |显示全部楼层
原帖由 alexhappy 于 2009-2-5 16:54 发表

unlink后别的进程可以再打开它吗?

不能,要不咋控制进程的唯一性呢?

[ 本帖最后由 fera 于 2009-2-5 17:16 编辑 ]

论坛徽章:
0
发表于 2009-02-05 17:48 |显示全部楼层
谢谢各位大虾, 我要考虑与实践一下.

然后给分!

论坛徽章:
0
发表于 2009-02-05 18:12 |显示全部楼层
原帖由 spiritX 于 2009-2-5 17:48 发表
谢谢各位大虾, 我要考虑与实践一下.

然后给分!

不用想了,俺的最简单实用
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP