linux进入子进程的命令是

linux进入子进程的命令是,第1张

linux是一个 多进程 多用户的 *** 作系统

ps(显示当前进程的状态)

ps -ef 查看当前linux 进程

ps -ef | grep 'mysqld' 过滤mysql的进程 (grep 过滤 ; | 管道符)

uid 用户id

pid 进程id

ppid 父进程id

CMD 启动该进程的命令

kill(删除执行中的进程)

kill -9 : kill -9 1982

-9 最高级别的关闭进程

小注:模拟运行着进程,可以使用tailf demo.txt;ps -ef |grep ‘tailf’

面试:现在在linux上运行着多个flask ,不确定有多少个进程,请以简短的命令,将这些进程杀死?

ps -ef | grep 'flask' | grep -v 'grep' | awk '{print "kill -9" $2}' | sh

排除grep批量找pid 命令执行

&(后台运行进程)

crontab(定时任务)

软件安装命令

rpm(管理安装套件)

yum(Shell前端软件包管理器)

Linux命令-查看进程命令:pstree

查看进程树,ps aux查看进程,如果进程太多看起来很不方便,可以使用pstree以树形方式显示正在运行的所有进程 pstree -p 查看进程树 还是太多了,可以使用管道符进行查找httpd(apa ...

Linux命令-终止进程命令:kill

kill -l 查看进程信号 常用信号 例如: 例子参见:Linux命令-查看进程命令:pstree

linux ps查看进程命令

linux ps查看进程命令ps命令作用:将某个时间点的程序运作情况撷取下来 实例: [root@linux ~]# ps aux [root@linux ~]# ps -lA [root@linux ...

Linux ps 命令查看进程启动及运行时间

Linux 实现 IPC 其中的一种方式——管道

管道又分:

1、无名管道:无名管道只能用于有亲缘关系的进程。

2、有名管道:有名管道用于任意两进程间通信。

你就可以把管道理解成位于进程内核空间的“文件”。

给文件加引号,是因为它和文件确实很像,因为它也有描述符。但是它确实又不是普通的本地文件,而是一种抽象的存在。

当进程使用 pipe 函数,就可以打开位于内核中的这个特殊“文件”。同时 pipe 函数会返回两个描述符,一个用于读,一个用于写。如果你使用 fstat函数来测试该描述符,可以发现此文件类型为 FIFO。

而无名管道的无名,指的就是这个虚幻的“文件”,它没有名字。本质上,pipe 函数会在进程内核空间申请一块内存(比如一个内存页,一般是 4KB),然后把这块内存当成一个先进先出(FIFO)的循环队列来存取数据,这一切都由 *** 作系统帮助我们实现了。

pipe 函数打开的文件描述符是通过参数(数组)传递出来的,而返回值表示打开成功(0)或失败(-1)。

它的参数是一个大小为 2 的数组。此数组的第 0 个元素用来接收以读的方式打开的描述符,而第 1 个元素用来接收以写的方式打开的描述符。也就是说,pipefd[0] 是用于读的,而 pipefd[1] 是用于写的。

打开了文件描述符后,就可以使用 read(pipefd[0]) 和 write(pipefd[1]) 来读写数据了。

注意事项

1、这两个分别用于读写的描述符必须同时打开才行,否则会出问题。

2、如果关闭读 (close(pipefd[0])) 端保留写端,继续向写端 (pipefd[1]) 端写数据(write 函数)的进程会收到 SIGPIPE 信号。

3、如果关闭写 (close(pipefd[1])) 端保留读端,继续向读端 (pipefd[0]) 端读数据(read 函数),read 函数会返回 0。

当在进程用 pipe 函数打开两个描述符后,我们可以 fork 出一个子进程。这样,子进程也会继承这两个描述符,而且这两个文件描述符的引用计数会变成 2。

如果你需要父进程向子进程发送数据,那么得把父进程的 pipefd[0] (读端)关闭,而在子进程中把 pipefd[1] 写端关闭,反之亦然。为什么要这样做?实际上是避免出错。传统上 pipe 管道只能用于半双工通信(即一端只能发,不能收;而另一端只能收不能发),为了安全起见,各个进程需要把不用的那一端关闭(本质上是引用计数减 1)。

步骤一:fork 子进程

步骤二:关闭父进程读端,关闭子进程写端

父进程 fork 出一个子进程,通过无名管道向子进程发送字符,子进程收到数据后将字符串中的小写字符转换成大写并输出。

有名管道打破了无名管道的限制,进化出了一个实实在在的 FIFO 类型的文件。这意味着即使没有亲缘关系的进程也可以互相通信了。所以,只要不同的进程打开 FIFO 文件,往此文件读写数据,就可以达到通信的目的。

1、文件属性前面标注的文件类型是 p

2、代表管道文件大小是 0

3、fifo 文件需要有读写两端,否则在打开 fifo 文件时会阻塞

通过命令 mkfifo 创建

通过函数 mkfifo创建

函数返回 0 表示成功,-1 失败。

例如:

cat 命令打印 test文件内容

接下来你的 cat 命令被阻塞住。

开启另一个终端,执行:

然后你会看到被阻塞的 cat 又继续执行完毕,在屏幕打印 “hello world”。如果你反过来执行上面两个命令,会发现先执行的那个总是被阻塞。

有两个程序,分别是发送端 send 和接收端面 recv。程序 send 从标准输入接收字符,并发送到程序 recv,同时 recv 将接收到的字符打印到屏幕。

发送端

接收端

编译

运行

因为 recv 端还没打开test文件,这时候 send 是阻塞状态的。

再开启另一个终端:

这时候 send 端和 recv 端都在终端显示has opend fifo

此时在 send 端输入数据,recv 打印。

父进程未结束,子进程先结束,会产生僵尸进程。

子进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用 exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。

即使是root身份kill -9也不能杀死僵尸进程。补救办法是杀死僵尸进程的父进程(僵尸进程的父进程必然存在),僵尸进程成为"孤儿进程",过继给1号进程init,init始终会负责清理僵尸进程。

僵尸进程的避免:

(1) 父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。

(2) 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父

进程会收到该信号,可以在handler中调用wait回收。

(3) 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN) 通知内

核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送

信号。

(4) 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进

程后退出,那么孙进程被init接管,孙进程结束后, init会回收。不过子进程的回收 还要自己

做。

建议你使用第三种方法,父进程直接忽略子进程的结束,留给内核作回收处理。这样就不

会产生僵尸进程。


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存