我们在前面完成了一个基本的服务程序,但是这个程序还有很多不足
1、进程执行的时候占用当前shell并且当shell关闭时,服务进程将会结束
2、进程的退出依靠ctrl + c 来完成,这种强制结束的方式非常的不友好
我们将在下面着手修改这两个问题
让程序以demo的形势运行
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
cout <<"server is begin" << endl;
daemon(1,0);
while(true)
{
cout << "server is running..." << endl;
sleep(1);
}
return 0;
}
执行
[liujinchun@localhost test]$ ./server
server is begin
这是我们发现当输出server is begin 之后,当前的shell 并不会占用,我们用 ps x命令查看下进程
[liujinchun@localhost test]$ ps x
PID TTY STAT TIME COMMAND
62373 ? S 0:02 sshd: liujinchun@pts/2
62374 pts/2 Ss 0:00 -bash
69182 ? Ss 0:00 ./server
69443 pts/2 R+ 0:00 ps x
我们看到 server进程的tty 显示为1个 ? 这个意思是server的进程并不会占用任何一个tty
在这个新的程序中我们使用了一个新的函数daemon(1,0),我们来看下这个函数的参数意义
int daemon(int nochdir, int noclose);
参数:
nochdir:当此参数为0时,会更改创建出的danmon的执行目录为根目录,否则(非0)时保持当前执行目录不变。
noclose:当次函数为0时,会将标准输入(0),标准输出(1),标准错误(2)重定向到/dev/null,否则保持原有标准输入(0),标准输出(1),标准错误(2)不变。
下面我们来结束程序
[liujinchun@localhost test]$ kill -2 69182
[liujinchun@localhost test]$ ps x
PID TTY STAT TIME COMMAND
62373 ? S 0:02 sshd: liujinchun@pts/2
62374 pts/2 Ss 0:00 -bash
69560 pts/2 R+ 0:00 ps x
通过kill命令向进程发送一个ctrl+c结束信号,这时我们查看进程已经不在了
我们再次修改一下我们的程序
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
cout <<"server is begin" << endl;
daemon(1,1);
while(true)
{
cout << "server is running..." << endl;
sleep(1);
}
cout <<"server is end" << endl;
return 0;
}
修改一下 damon函数的第二个参数,他会让程序在当前shell还没有结束的时候依旧像当前tty输出数据
然后我们在程序的后面增加了一行话。
执行程序我们会看到如下结果
[liujinchun@localhost test]$ ./server
server is begin
[liujinchun@localhost test]$ server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
程序已经在向当前的tty输出。开启一个新的shell窗口创建一个新的tty,并用kill命令向server进程发送ctrl + c 信号。这时我们会看到程序并没有打印出 server is end。这是因为 ctrl + c 会让程序直接结束 。如果你想在服务进程退出的时候进程一些工作怎么办呢。我们需要截获这个信号并进行自己的处理。
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;
static bool run = true;
bool isRun()
{
return run;
}
static void ctrlHandler( int signum )
{
run = false;
}
int main()
{
cout <<"server is begin" << endl;
struct sigaction sig;
sig.sa_handler = ctrlHandler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sigaction(SIGINT,&sig,NULL);
daemon(1,1);
while(isRun())
{
cout << "server is running..." << endl;
sleep(1);
}
cout <<"server is end" << endl;
return 0;
}
运行并发送kill信号
[liujinchun@localhost test]$ ./server
server is begin
server is running...
[liujinchun@localhost test]$ server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is running...
server is end
我们看到程序执行了退出命令
网友评论