3.4.16.让程序不能被多次运行
3.4.16.1、问题
(1)因为守护进程是长时间运行而不退出,因此./a.out执行一次就有一个进程,执行多次就有多个进程。
(2)这样并不是我们想要的。我们守护进程一般都是服务器,服务器程序只要运行一个就够了,多次同时运行并没有意义甚至会带来错误。
(3)因此我们希望我们的程序具有一个单例运行的功能。意思就是说当我们./a.out去运行程序时,如果当前还没有这个程序的进程运行则运行之,如果之前已经有一个这个程序的进程在运行则本次运行直接退出(提示程序已经在运行)。
我们只希望 这个程序 只是在系统里执行一次!!!,工作当中 肯定会用到
3.4.16.2、实现方法:
(1)最常用的一种方法就是:用一个文件的存在与否来做标志。具体做法是程序在执行之初去判断一个特定的文件是否存在,若存在则标明进程已经在运行,若不存在则标明进程没有在运行。然后运行程序时去创建这个文件。当程序结束的时候去删除这个文件即可。
(2)这个特定文件要古怪一点,确保不会凑巧真的在电脑中存在的。
代码: 先 写一个 提示 重复打开 文件 的程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
/* 先声明一个文件, 在/var/目录下有一个 da_mo_fei_ying_single 的文件*/
#define FILE "/var/da_mo_fei_ying_single"
/*******************************************
O_RDWR : 可读可写
O_TRUNC : 会把原有内容删除 。 英文读:欧擦克
O_CREAT : 如果FILE没有这个文件,就会新建一个 FILE
O_EXCL : 我们希望的效果是:如果我CREAT要创建的是一个已经存在的名字的文件,则给我报错,不要去创建。
这个效果就要靠O_EXCL标志和O_CREAT标志来结合使用。
当这连个标志一起的时候,则没有文件时创建文件,有这个文件时会报错提醒我们。
O_APPEND : 接续添加要写入的内容 。 英文读:欧额盆得
***********************************/
int main(void)
{
int fd = -1;
/* 程序 执行之初,先去判断文件 是否 存在 */
fd = open(FILE,O_RDWR | O_TRUNC | O_CREAT | O_EXCL , 0664);
/* 如果fd 小于 0, 说明文件打开失败了 */
if(fd < 0)
{
/* 文件打开失败,errno 输出错误码,EEXIST意思是文件 已经存在 的错误码 */
if(errno == EEXIST)
{
printf("错误:是文件已经存在\n");
return -1;
}
}
printf("文件已打开\n");
return 0;
}
运行结果:
代码:
程序在执行之初去判断一个特定的文件是否存在,
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
/* 先声明一个文件, 在/var/目录下有一个 da_mo_fei_ying_single 的文件*/
#define FILE "/var/da_mo_fei_ying_single"
void delete_file();
/*******************************************
O_RDWR : 可读可写
O_TRUNC : 会把原有内容删除 。 英文读:欧擦克
O_CREAT : 如果FILE没有这个文件,就会新建一个 FILE
O_EXCL : 我们希望的效果是:如果我CREAT要创建的是一个已经存在的名字的文件,则给我报错,不要去创建。
这个效果就要靠O_EXCL标志和O_CREAT标志来结合使用。
当这连个标志一起的时候,则没有文件时创建文件,有这个文件时会报错提醒我们。
O_APPEND : 接续添加要写入的内容 。 英文读:欧额盆得
***********************************/
int main(void)
{
int fd = -1;
/* 程序 执行之初,先去判断文件 是否 存在 */
fd = open(FILE,O_RDWR | O_TRUNC | O_CREAT | O_EXCL , 0664);
/* 如果fd 小于 0, 说明文件打开失败了 */
if(fd < 0)
{
/* 文件打开失败,errno 输出错误码,EEXIST意思是文件 已经存在 的错误码 */
if(errno == EEXIST)
{
printf("错误:进程已经存在,请不要重复执行\n");
return -1;
}
}
/* 程序结束后,删除 da_mo_fei_ying_single 文件 */
atexit(delete_file); /* atexit: 类似于回调函数,当整个程序执行完之后,才会调用 atexit */
int i = 0;
for(i=0; i<10; i++)
{
printf("I am runing..... %d\n", i);
sleep(1);
}
return 0;
}
void delete_file()
{
remove(FILE);
}
/* 3.4.1.程序的开始和结束 atexit();*/
运行结果:
运行结果 1
运行结果 2
代码来自朱老师物联网大讲堂