一.tcp接入线程池(使用线程池)
1.tcp初步接入线程池
我们设置了对应的任务是死循环,那么线程池提供服务,就显得有不太合适。我们给线程池抛入的任务都是短任务
因为他并没有访问任何类内成员,所以可以把执行方法提到类外,执行任务时就可以不用把服务和类绑定了bind(&ServerTcp::transService, this,。②threadRoutine也没用了
代码:
提交了2022-12-23对tcp初步接上线程池的代码 · cf60e99 · beyond/linux - Gitee.com
2.popen
作用:创建管道,再fork创建子进程,子进程调用exec执行命令command,执行完后通过管道将数据交给父进程,父进程再把数据传入返回值中的文件描述符中。使用完把文件pclose关闭即可
FILE *popen(const char *command, const char *type);
command:执行一个命令command。type:r读还是w写方式打开
返回值:底层的pipe/fork调用失败返回nullptr
二.守护进程/精灵进程——部署
这两种是同一种进程的不同翻译,是特殊的孤儿进程,不但运行在后台,最主要的是脱离了与终端和登录会话的所有联系,也就是默默的运行在后台不想受到任何影响,并且退出后不会成为僵尸进程。
一般以服务器的方式工作,对外提供服务的服务器,都是以守护进程(精灵进程)的方式在服务器中工作的,一旦启动之后,除非用户主动关闭,否则,一直会在运行
守护进程特点:①父进程是系统。②守护进程命名通常以d结尾
1.介绍PGID,SID等各个名称
(1)介绍
PPID:父进程的id。PID:进程本身的id。PGID:当前进程所属的进程组。(同组进程的第一个进程一般是进程组的组长)SID:当前进程的会话id。
COMMAND:命令。TIME:进程启动的时长。UID:用户名映射后的数字,用户UID。
TPGID:当前进程组和终端相关的信息,-1 说明进程和终端无关系,非-1说明有关。
TTY:哪一个终端
(2)进程组:
2.会话,守护进程/精灵进程定义
用户登录时会建立一个会话,会话内部会构建一个前台进程组 和 0个或者多个后台进程组,linux下客户端登录时 会给我们加载bash,bash就是前台进程组。(windows下的注销就是新建立一个会话)前台进程组必须有一个,而且任何时刻只能有一个。
bash构建了一个会话,自己是会话前台进程组,后续如果我们自己再新启进程 或者 启动进程组,这些进程都属于bash的会话!
在命令行中启动一个进程./mytest 可以称作:在会话中启动一个进程组(可以只有一个进程),来完成某种任务,所有会话内的进程fork创建子进程,一般依旧属于当前会话! !
让某个后台进程(例如我们自己写的网络服务器进程)脱离当前会话,让它独立的在计算机中形成一个新会话,自成进程组,这种进程叫做守护进程/精灵进程。
三. 如何使服务器形成守护进程?
1.为什么需要使服务器成为守护进程
我们自己写的网络服务器进程会受到计算机上客户端或者shell的影响,即:如果我们的shell掉线了我们写的网络服务器会终止,我们电脑用户注销了,或者电脑关了,我们写的网络服务器进程都会终止,如果我们写的网络服务器成为守护进程:他脱离当前会话,让它独立的在计算机中形成一个新会话,自成进程组,他便不受计算机上客户端会话或者shell的限制,就算我们把电脑关了,shell也关了,这个服务器也会在云端一直提供服务。(这也是抖音随时打开都能刷的原因)想结束守护进程,ps axj|grep 进程名,然后kill -9 即可结束。
2.形成守护进程的核心步骤——setsid
守护进程要编写必须调用一个函数setsid():将调用进程设置成为独立的会话
注意:进程组的组长不可调用setsid();(组长本来就是一个会话的组长)
3.setsid
作用:使调用setsid的进程成为一个新的会话,并成为会话内某个进程组的组长
pid_t setsid(void);
返回值:成功返回调用进程的pid,失败返回-1错误码被设置
4.形成守护进程全步骤
(1)必做:fork+setsid()
那我如何不成为组长以便调用setsid呢?——bash中新启动第一个进程一定成为组长,所以你可以成为进程组内的第二个进程。即:常规做法:fork()子进程,子进程就不再是组长进程了,它就可以成功调用setsid(); ————
if(fork() > 0) exit(0) ;
setsid() ;
(2)选做:
①忽略SIGPIPE信号:
系统的管道:写端一直在写,读端关闭,写端会被终止,被信号终止SIGPIPE。网络套接字同理!
网络的套接字:server向client写入,client (close) 关闭了,server也会收到SIGPIPE,server会直接被终止,为了防止服务器server异常退出,需要 忽略SIGPIPE信号
②更改守护进程的工作目录,如何更改进程的工作目录?——chdir()
(3)一般守护进程都要做的:
1. 因为守护进程与标准输入,标准输出,标准错误已经没关系了,所以close(0, 1,2) 守护进程获取输入或写入都是和网络有关,不会从键盘获取,不会往显示器输出。(很少有人这样做,因为兼容性不好,会导致代码中的打印代码报错)
2.类似于所有Linux下的一个”垃圾桶(文件黑洞)“,凡是从 /dev/null 里面读/写一概被丢弃
这些输入输出的数据会全部被丢弃:
[whb@ecs-144421 ~]$ echo "hello wrold" >> /dev/null
[whb@ecs-144421 ~]$ echo cat < /dev/null
推荐做法:打开/dev/null, 并且对 0,1,2 进行重定向!
总结:1.忽略SIGPIPE
2.更改进程的工作目录
3.让自己不要成为进程组组长
4.设置自己是一个独立的会话
5.重定向0,1,2
5.重定向0,1,2后,可以将打印信息保存入一个文件serverTcp.log中
log.hpp中: