linux c程序开机自启

linux c程序开机自启,第1张

实现方式1(高大上方式):通过在/etc/init.d下添加启动/停止脚步,并在相应运行级别的/etc/rc.d/rcX.d目录下建立相应软连接的方式。这是LInux标准服务的启动方式,同时也支持采用service XXX start的方式启动和关闭。

1. 在/etc/init.d下放置相应启动程序的脚本,脚本必须实现start, stop, restart三和 *** 作。可以参考该目录已有的脚本,改写一下就行。

2. 在/etc/rc.d/rcX.d(如rc3.d)目录下用ln建立命令建立相应的link文件,K开头为关机时调用的,S开头为开机时使用的,后面接的数字表明这个服务相对于其它服务的启动优先级。可以参考该目录已有的连接文件名,ln一下就行。

实现方式2(菜鸟方式): 修改/etc/rc.d/rc.local。这个文件一般会放一些用户个性化的命令。

有点像早期 DOS 年代的 autoexec.bat 与 config.sys, 它就是一个脚本,在里头添上你的应用就行了。

可以分三步来做:

做两个简单的守护进程,并能正常运行

监控进程是否在运行

启动进程

综合起来就可以了,代码如下:

被监控进程thisisatest.c(来自http://www.cnblogs.com/ringwang/p/3528093.html):

#include<unistd.h>

#include<signal.h>

#include<stdio.h>

#include<stdlib.h>

#include<sys/param.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<time.h>

void init_daemon()

{

int pid

int i

pid=fork()

if(pid<0)  

  exit(1) //创建错误,退出

else if(pid>0) //父进程退出

  exit(0)

setsid()//使子进程成为组长

pid=fork()

if(pid>0)

  exit(0)//再次退出,使进程不是组长,这样进程就不会打开控制终端

else if(pid<0)  

  exit(1)

//关闭进程打开的文件句柄

for(i=0i<NOFILEi++)

  close(i)

chdir("/root/test") //改变目录

umask(0)//重设文件创建的掩码

return

}

void main()

{

  FILE *fp

  time_t t

  init_daemon()

  while(1)

  {

      sleep(60)//等待一分钟再写入

      fp=fopen("testfork2.log","a")

      if(fp>=0)

      {

          time(&t)

          fprintf(fp,"current time is:%s\n",asctime(localtime(&t))) //转换为本地时间输出

          fclose(fp)

      }

  }

  return

}

监控进程monitor.c:

#include<unistd.h>

#include<signal.h>

#include<stdio.h>

#include<stdlib.h>

#include<sys/param.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<time.h>

#include<sys/wait.h>

#include<fcntl.h>

#include<limits.h>

#define BUFSZ 150

void init_daemon()

{

int pid

int i

pid=fork()

if(pid<0)

  exit(1) //创建错误,退出

else if(pid>0) //父进程退出

  exit(0)

setsid()//使子进程成为组长

pid=fork()

if(pid>0)

  exit(0)//再次退出,使进程不是组长,这样进程就不会打开控制终端

else if(pid<0)

  exit(1)

//关闭进程打开的文件句柄

for(i=0i<NOFILEi++)

  close(i)

chdir("/root/test") //改变目录

umask(0)//重设文件创建的掩码

return

}

void err_quit(char *msg)

{

perror(msg)

exit(EXIT_FAILURE)

}

// 判断程序是否在运行

int does_service_work()

{

FILE* fp

int count

char buf[BUFSZ]

char command[150]

sprintf(command, "ps -ef | grep thisisatest | grep -v grep | wc -l" )

if((fp = popen(command,"r")) == NULL)

err_quit("popen")

if( (fgets(buf,BUFSZ,fp))!= NULL )

{

count = atoi(buf)

}

pclose(fp)

  return count

// exit(EXIT_SUCCESS)

}

void main()

{

  FILE *fp

  time_t t

  int count

  init_daemon()

  while(1)

  {

      sleep(10)//等待一分钟再写入

      fp=fopen("testfork3.log","a")

      if(fp>=0)

      {

          count = does_service_work()

          time(&t)

          if(count>0)

              fprintf(fp,"current time is:%s and the process exists, the count is %d\n",asctime(localtime(&t)), count) //转换为本地时间输出

          else

          {

              fprintf(fp,"current time is:%s and the process does not exist, restart it!\n",asctime(localtime(&t))) //转换为本地时间输出

              system("/home/user/daemon/thisisatest")//启动服务

          }

          fclose(fp)

      }

  }

  return

}

具体CMD命令:

cc thisisatest.c -o thisisatest

./thisisatest

cc monitor.c -o monitor

./monitor

tail -f testfork3.log   -- 查看日志

HOHO相当有难度的问题。

首先,我想知道的是如何叫意外杀死,一切没有执行完的都算是意外杀死么?我看用shell解决是比较合适的。大致流程如下:

首先我希望你有1234的源代码,因为我不知道你所谓的意外杀死是什么情况下意外杀死,比如通过kill来发送信号杀死他。请注意,如果你程序执行出现异常也是通过信号来杀死,不过是内核发送的,而不是你自己来发送的。所以我希望你修改1234的源代码,在他正常结束的情况下,你最好有个输出标志标识他正常结束。比如你的程序是C写的,那么希望你在正常结束后调用一个printf("success end")这个应该不难。

紧接着,你写一个shell脚本,这个脚本应该是这样

绝对路径/1234 >绝对路径/my.txt,以后想启动这个进程就用这个脚本来启动。

在希望你写一个脚本,这个脚本执行ps -le首先查看进程里面是否还存在1234这个进程,如果有就什么都不做退出,如果没有了,那你就检查my.txt文件看是否是正常结束了,如果正常结束就从cron守护进程的配置文件移除我这个检测脚本。如果没有找到 success end的话,那么就再次启动。

最后将这个脚本加到cron守护进程的配置文件中,定时启动它检测。

有点麻烦,不过这是我能想到的办法了,也许其它人有更好的办法。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8407989.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-16
下一篇 2023-04-16

发表评论

登录后才能评论

评论列表(0条)

保存