首页 » SEO优化 » phplinux多过程技巧_多进程一文看懂Linux进程通信的FIFO管道及多进程若何实现

phplinux多过程技巧_多进程一文看懂Linux进程通信的FIFO管道及多进程若何实现

访客 2024-12-08 0

扫一扫用手机浏览

文章目录 [+]

先大略先容下观点内容。

有名管道--FIFO

进程间通信的办法有:旗子暗记通信机制; 共享存储区通信机制;共享文件通信机制;通报通信机制.

phplinux多过程技巧_多进程一文看懂Linux进程通信的FIFO管道及多进程若何实现

管道是连接读写进程的一个分外文件,许可进程按前辈先出办法传送数据,也能使进程同步实行操作。
发送进程以字符流形式把大量数据送入管道,吸收进程从管道中吸收数据,以是叫管道通信.

phplinux多过程技巧_多进程一文看懂Linux进程通信的FIFO管道及多进程若何实现
(图片来自网络侵删)

管道的本色是一个共享文件,基本上可借助于文件系统的机制实现,包括(管道)文件的创建、打开、关闭和读写.进程对通信机构的利用该当互斥,一个进程正在利用某个管道写入或读出数据时,另一个进程就必须等待.发送者和吸收者双方必须能够知道对方是否存在,如果对方已经不存在,就没有必要再发送信息.管道长度有限,发送信息和吸收信息之间要实现精确的同步关系,当写进程把一定数量的数据写入管道,就去就寝等待,直到读进程取走数据后,把它唤醒。
管道是一种文件,可以调用read、write和close等操作文件的接口来操作管道。
另一方面管道又不是一种普通的文件,它属于一种独特的文件系统:pipefs。
管道的实质是内核掩护了一块缓冲区与管道文件干系联,对管道文件的操作,被内核转换成对这块缓冲区内存的操作。

管道是第一个广泛运用的进程间通信手段。
日常在终端实行shell命令时,会大量用到管道。
但管道的毛病在于只能在有亲缘关系(有共同的先人)的进程之间利用。
为了打破这个限定,后来引入了命名管道。

FIFO也称为有名管道,它是一种文件类型。
FIFO大略理解,便是它能把两个不干系的进程联系起来,FIFO就像一个公共通道,办理了不同进程之间的“代沟”。
普通的无名管道只能让干系的进程进行沟通(比如父shell和子shell之间)。

实验--FIFO通信

这里大略仿照一个FIFO通信的过程,紧张有两个进程。

#!/bin/bash#Client.sh#不断向fifo写入数据 tmp_fifo=\"大众/tmp/test.fifo\"大众rm -f $tmp_fifomkfifo $tmp_fifoexec 6<>$tmp_fifo #这句话能把管道变成非壅塞!
i=0while :dosleep 1 # 1秒写一次echo \公众$i\"大众 >&6 echo \"大众$i\"大众 #输出到终真个时候要小心,会覆盖你的终端,以是要停滞,最好直接挂起进程!

let i++done exec 6>&-

#!/bin/bash#Server.sh#不断从fifo中读出数据 tmp_fifo=\公众/tmp/test.fifo\"大众echo \"大众$tmp_fifo\公众exec 6<>$tmp_fifo #建立一个绑定 while :do read TEXTsleep 1echo \"大众$TEXT\"大众 #每1s就读取一个数据,并且打印到终端,要停滞,最好挂起进程!
done <&6

开启两个终端,分别实行两个脚本,就能看到在终端B中从fifo中读取到的数据,如果在终端B中把每次读fifo的间隔给改成2秒,就更能解释问题了。

上面的程序,在实验的时候最好通过不断挂起A进程来查看,然后不雅观察B进程的输出。
你会知道FIFO全体是怎么跑的。


下面大略分了4种情形,也是通过实验来测试,难度会轻微大一点。

实验测试--不同写法对性能的影响1、多进程情形1:

#!/bin/bashtemp_fifo_file=$$.info #以当提高程号,为临时管道取名mkfifo $temp_fifo_file #创建临时管道exec 6<>$temp_fifo_file #创建标识为6,可以对管道进行读写rm $temp_fifo_file #清空管道内容 function f_sleep { sleep 2} temp_thread=2 #进程数#for循环:往fifo管道文件中写入2个空行(这个必须大于或即是temp_thread,要不外程写哪里?) for ((i=0;i<temp_thread;i++)) #为进程创建相应的占位do echo #每个echo输出一个回车,为每个进程创建一个占位done >&6 #将占位信息写入标识为6的管道#{}这部分语句被放入后台作为一个子进程实行,以是不必每次等待5秒后实行下一个,{}这部分的echo $$,$i,`date`险些是同时完成的,当fifo中2个空行#读完后for循环连续等待read中读取fifo数据,当后台的2个子进程等待5秒后,按次序排队往fifo输入空行,这样fifo又有数据,for语句连续实行for ((i=0;i<6;i++)) do read -u6 #获取标识为6的占位,从文件描述符6中读取行(实际指向fifo管道) { f_sleep echo $$,$i,`date +%H:%M:%S` sleep 5 echo $$,$i,`date` echo >&6 #>>>>>当任务实行完后,会开释管道占位,以是补充一个占位,实在是再次往fifo管道文件中写入一个空行 }& done <&6 #将标识为6的管道作为标准输入 wait #等待所有任务完成exec 6>&- #关闭标识为6的管道

把稳不雅观察每个日期之间的韶光间隔。

大略理解:同时开两个进程,用了两个循环在后台跑,过了2s先跑了date +%H:%M:%S,然后过了5s后两个进程跑了date,然后重新从fifo管道读取两个空行,连续for循环。

2、多进程情形2:

#!/bin/bashtemp_fifo_file=$$.info #以当提高程号,为临时管道取名mkfifo $temp_fifo_file #创建临时管道exec 6<>$temp_fifo_file #创建标识为6,可以对管道进行读写rm $temp_fifo_file #清空管道内容 function f_sleep { sleep 2} temp_thread=2 #进程数 for ((i=0;i<temp_thread;i++)) #为进程创建相应的占位do echo #每个echo输出一个回车,为每个进程创建一个占位done >&6 #将占位信息写入标识为6的管道 for ((i=0;i<6;i++)) do read #获取标识为6的占位 { f_sleep echo $$,$i,`date +%H:%M:%S` }& #>>>>>在后台实行{}中的任务 sleep 5 echo $$,$i,`date` echo >&6 #>>>>>当任务实行完后,会开释管道占位,以是补充一个占位done <&6 #将标识为6的管道作为标准输入 wait #等待所有任务完成exec 6>&- #关闭标识为6的管道

这里不雅观察我赤色标记的部分,基本便是改变的地方了。

合理要不雅观察每个日期之间间隔的韶光,然后来剖析。

大略理解:开了2个进程,1个在后台实行,1个在前台实行,(过了2s先跑了date +%H:%M:%S)这个在后台跑,(过了5s后两个进程跑了date)这个在前台跑,一次统共是5s循环,统共跑6次。

3、多进程情形3:

#!/bin/bashtemp_fifo_file=$$.info #以当提高程号,为临时管道取名mkfifo $temp_fifo_file #创建临时管道exec 6<>$temp_fifo_file #创建标识为6,可以对管道进行读写rm $temp_fifo_file #清空管道内容 function f_sleep { sleep 2 echo >&6 #>>>>>当任务实行完后,会开释管道占位,以是补充一个占位} temp_thread=2 #进程数 for ((i=0;i<temp_thread;i++)) #为进程创建相应的占位do echo #每个echo输出一个回车,为每个进程创建一个占位done >&6 #将占位信息写入标识为6的管道 for ((i=0;i<6;i++)) do read #获取标识为6的占位 { f_sleep echo $$,$i,`date +%H:%M:%S` }& #>>>>>在后台实行{}中的任务 sleep 5 echo $$,$i,`date`done <&6 #将标识为6的管道作为标准输入 wait #等待所有任务完成exec 6>&- #关闭标识为6的管道

把稳不雅观察赤色框部分。

结果输出:

大略理解:开了2个进程,1个进程在后台实行,个中后台进程在管道有2个占位,但实际只用了1个,(过了2s先跑了date +%H:%M:%S)这个在后台跑,(过了5s后两个进程跑了date)这个在前台跑,一次5s循环,统共跑6次。

4、多进程情形4:

#!/bin/bashtemp_fifo_file=$$.info #以当提高程号,为临时管道取名mkfifo $temp_fifo_file #创建临时管道exec 6<>$temp_fifo_file #创建标识为6,可以对管道进行读写rm $temp_fifo_file #清空管道内容 function f_sleep { sleep 2 echo >&6 #>>>>>当任务实行完后,会开释管道占位,以是补充一个占位} temp_thread=2 #进程数 for ((i=0;i<temp_thread;i++)) #为进程创建相应的占位do echo #每个echo输出一个回车,为每个进程创建一个占位done >&6 #将占位信息写入标识为6的管道 for ((i=0;i<6;i++)) do read #获取标识为6的占位 { f_sleep echo $$,$i,`date +%H:%M:%S` sleep 5 echo $$,$i,`date` }& #>>>>>在后台实行{}中的任务done <&6 #将标识为6的管道作为标准输入 wait #等待所有任务完成exec 6>&- #关闭标识为6的管道

大略理解:两个后台进程在跑,echo >&6在管道增加一个占位,现在变成3个占位,

从管道读第1个占位,先用2个后台子进程跑循环1(过了2s先跑了循环1的date +%H:%M:%S,从循环1一开始过了5s后循环1就跑到date了),然后从管道读第2个占位,再用2个后台子进程跑循环2,末了读第3个占位,用2个后台子进程跑循环3,由于是fifo(前辈先出),以是每次读取占位都须要算上f_sleep的韶光2s。

总结

FIFO的涌现,极好地办理了系统在运用过程中产生的大量的中间临时文件的问题。
FIFO可以被shell调用使数据从一个进程到另一个进程,系统不必为该中间通道去烦恼清理不必要的垃圾,或者去开释该通道的资源,它可以被留做后来的进程利用。
并且规避了匿名管道在浸染域的限定,可运用于不干系的进程之间。

上面的理解该当是有些不对的地方,希望大家示正,下方留言一起谈论~

后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~

标签:

相关文章