<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> 在我開發Android的過程中遇到Service組件簡單的將就是不需要介面的背後進程,默默執行任務。現在我們學習一下Linux下守護進程Service是怎麼實現的,也同時學習一下通過shell指令碼來控制進程的開關。</span>
守護進程實現有著預設的思路fork父子進程,關閉父進程,將子進程進行與控制台脫離的操作,我這邊的守護進程demo實現的是通過訊號來控制守護進程的輸出。首先看一下代碼:
#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ipc.h>#include <sys/shm.h>#include <signal.h>#include <syslog.h>#include <errno.h> int mysignal(int signo,void(*func)(int)){ struct sigaction act,oact; act.sa_handler = func; sigemptyset(&act.sa_mask); act.sa_flags = 0; return sigaction(signo,&act,&oact); }void setDaemon(){ pid_t pid,sid; pid = fork(); if(pid < 0) { printf("fork failuer : %s\n",strerror(errno)); exit(EXIT_FAILURE); } if(pid > 0) { exit(EXIT_SUCCESS); } if( (sid = setsid()) < 0 ) { printf("set sid failure: %s\n",strerror(errno)); exit(EXIT_FAILURE); }}void listenFifo(){ const char* filename = "shaofifo"; int len = 0; char buf[1024]; memset(buf,0,sizeof(buf)); int fd = open(filename,O_RDONLY); if(fd == -1) { printf("open failure :%s\n",strerror(errno)); exit(EXIT_FAILURE); } len = read(fd,buf,sizeof(buf)); if(len > 0) { if( buf[strlen(buf) -1] == '\n') { buf[strlen(buf) -1] = 0; } close(STDOUT_FILENO); open(buf,O_WRONLY); } }void Catch_Signal(int signo){ switch(signo) { case SIGINT: listenFifo(); break; }} int main(int arg,char* args[]){ setDaemon(); mysignal(SIGINT,Catch_Signal); while(1) { puts("hello world !!"); sleep(1); } return EXIT_SUCCESS;}
然後 我們在管道檔案輸入另外一個控制台的裝置路徑,子進程就是守護進程會關閉標準輸出 然後接收訊號讀取管道檔案中的裝置路徑,開啟裝置,繼續輸出
在shaofifo管道檔案輸入裝置路徑,子進程讀取後輸出內容 這裡主要是學習了守護進程的實現 setsid()方法就是讓子進程脫離控制台
一般守護進程是需要shell指令碼進行控制的 ,看一下shell指令碼的實現
#! /bin/shWHOAMI=`whoami`PID=`ps -u $WHOAMI | grep service | awk '{print $1}'`if( test "$1" = "start") then if(test "$PID" = "") then ./service fifiif(test "$1" = "stop")then if(test "$PID" != "") then kill $PID fifiif(test "$1" = "status")then if(test "$PID" = "") then echo "not run" fi if(test "$PID" != "")then echo "run" fi fi
到這邊 通過shell指令碼控制守護進程的實現到此為止。。