Tutorial: Cross-platform background process forking without extensions in PHP
There are plenty of ways to fork new processes in PHP. You can use shell functions like exec() or shell(), the pcntl_* function set in the Process Control extension or stream/filesystem functions such as popen(). In this article, we're going to look at the latter of these, and learn:
- How to make it work on both Windows and Linux
- How to make the forked process run in the background
- How to communicate with the forked process
- How to fork more than one process
- How to cleanly terminate the forked process from the parent script
Why would we want to fork processes from PHP anyway?
The most common reason is because we want to get results from an external application and use them in the main script. We may also want to run a process that performs some action that is awkward in PHP, for example creating tarballs in backup scripts or modifying system configuration in maintenance scripts. You may want to create worker threads which do a long-running task and periodically report back their status. Finally, we may want to run processes periodically on a timer (see my PHPCron article for details on that).
Some things are better served by using threads due to the reduced overhead and lack of need to communicate between processes, but threading support in PHP is quite disastrous so forking a new process is a bit more bulletproof.
Forking a new process
You can fork a new process like this:
function startFork($path, $file, $args)
{
chdir($path);
if (substr(PHP_OS, 0, 3) == 'WIN')
$proc = popen('start /b php "' . $path . '\\' . $file . '" ' . $args, 'r');
else
$proc = popen('php ' . $path . '/' . $file . ' ' . $args . ' &', 'r');
return $proc;
}
This particular example assumes you're running another PHP script; if you're not, just remove the references to 'php ' from the code above. Note that changing the current directory with chdir() might have unpredictable consequences, so only do so if necessary, or change the directory back afterwards.
In Windows, start /b forks a new process without opening a new shell window, and makes it run in the background. In UNIX, appending the call with & also makes the process run in the background. The appropriate command is generated depending which platform PHP is running on by examining the PHP_OS constant.
Receiving data from the process
popen() returns a stream resource which can be manipulated just like a regular file. As the process outputs data, you can retrieve it as follows:
while (!feof($proc)) {
$data = fgets($proc);
// Do something with the data
}
The 'end of the file' will never be reached until the process stops running, so the while loop will merely stall until data is received. fgets() will stall until a newline is read, thereby retrieving one line of data at a time. You can use other stream reading functions instead if you want different behaviour.
If you're writing the child process yourself, you can make life easier by designing it to output data in a machine-readable format that can be easily parsed by PHP with functions like split() or regular expression functions.
When the process ends, call:
pclose($proc);
to close the stream.
Notice that if an error occurs, popen() will still return a resource handle so that the error text can be read. Make sure you check for this when parsing the incoming data.
Under UNIX, if the errors are sent to stderr, append 2>&1 to the line which forks the process to cause stderr to be redirected to stdout.
Running a background process and ignoring its output
If you don't care what happens to the child process, you can simply use the following line to invoke it:
pclose(startFork($path, $file, $args));
and the output will be discarded. The child process will run in the background without stalling the parent script.
Terminating a forked process from the parent script
There are various ways to do this but a simple one is to just create a so-called "kill file" that is monitored by the child process and triggers it to quit when found.
In the parent process:
$killFile = dirname(__FILE__) . '/child.die';
...
function stopFork()
{
global $proc, $killFile;
touch($killFile);
sleep(2);
pclose($proc);
}
In the child process:
$killFile = dirname(__FILE__) . '/child.die';
while (!file_exists($killFile)) {
// Do worker task and output status
}
while (file_exists($killFile)) {
@unlink($killFile);
sleep(1);
clearstatcache();
}
The child process runs its repetitive task in the first while loop, continuing as long as the kill file hasn't been created. Once it has been created, it moves to the second while loop which keeps trying to delete it until it succeeds, then the child process exits (make sure your directory permissions are set correctly to avoid an infinite loop).
When stopFork() is called in the parent process, the kill file is created with touch(), a short pause is made and then the process handle is closed. Not introducing a pause before closing the stream can cause the kill file not to be deleted and the child process to hang.
The above code assumes that the parent and child are both running in the same directory. If this is not the case, you will need to alter the definition of $killFile appropriately.
Ensuring child processes are always killed when the parent script ends
It's vital that child processes which act as worker threads aren't left hanging around after the main script has finished executing. If you leave orphan processes running, they may behave undesirably, create memory leaks, and on Windows if you call the CLI version of PHP the prompt will become unusable. To avoid this, attach stopFork() to the shutdown handler as follows:
register_shutdown_function('stopFork');
This will make sure that - however the main script is ended - the child processes are always killed off first.
Forking more than one process
This is as simple as repeating the above steps for as many processes as you need; however, if you are using the kill file technique to signal the child processes to end, you need to use a different kill file for each process. If you are forking the same process multiple times (multiple identical worker threads), you will want to pass the name of the kill file for each as an argument to the child process, eg:
startFork($path, $file, '/path/to/killfile1 ' . $args); startFork($path, $file, '/path/to/killfile2 ' . $args);
In the child process, retrieve the name of the kill file to monitor as follows:
$killFile = $argv[1];
Usage example
I use the techniques above to measure the bitrate of several streaming audio servers. The rate of incoming data must be measured per second for several servers and therefore this requires background worker threads (or processes in this case). The background worker is another PHP script which is instanced once for each server to measure.
The child processes return one line of data every second in a format like:
X Y Z
where X is a count of the amount of data received in the last second, and Y and Z are moving averages. The intervals of each moving average to measure are passed as parameters to the child script. To parse the data in the parent is easy:
$movingAverages = split(' ', fgets($proc));
$lastSecond = array_shift($movingAverages);
This leaves X in $lastSecond and all the remaining numbers in the $movingAverages array. This is a perfect of example of why it's important to format your child process output as something that is easily parsable by the parent script.
I hope you found this article useful. Please leave any comments below!
Printer-friendly version- 2875 reads
Looking For discountchanel
Looking For discountchanel
replica
Beautifulgucci handbags for sale
油墨
Balenciagafor sale
Looking For discountchanel
If you want to buylouis
vuitton
丝印器材
Looking For discountchanel
handbags
Beautifulgucci for sale
The store online sells theBalenciaga
bags
different kinds oflouis vuitton for
cheap
网版烤箱
ghd straighteners for Cheap
Wholesale
If you want to buylouis vuitton
bag
different kinds oflouis vuitton
handbag for cheap
replica louis vuitton bag for for
Cheap Wholesale
ghd very cheap
china Wholesale
ghd hair straighteners for Cheap
Wholesale
移印器材
replica louis vuitton bag for
Cheap Wholesale
常德SEO
陈水博客从事专业常德网站建设、常德网站优化与网站建设培训,为常德企业提供常德seo,常德SEO优化,常德网站建设,有着多年的seo优化服务网站策划经验。
Cheap Timberland Boots Sale
Cheap Timberland Boots Sale - More than 1000 customers have got thecheap timberland boots ,
Timberland Boots on sale. We hold the most competitive price, the first class service,buy now!
pink ghd straighteners
Ghd straighteners uk - buy the cheapest pink ghd straighteners in the UK.Use Compare ghd to find the biggest savings on ghd iv pink mk4,ghd flat Irons,ghd iv styelers and ghd Hair Straighteners pink.Cheap ghd uk hair straighteners found here.
tall black uggs
We supply UGG Boots UK ,black tall ugg boots,UGG Bailey Button,low price,offerWoolboots.com must be your best choice!
chi hair straightener
Save 60% off chi hair straighteners,we offer best Pink CHI Flat Iron ,Chi Camo Blue Ceramic Flat Iron in the market and 100% Quality Guarantee.
大阪 デリヘル
大阪 デリヘル
大阪 高収入求人
中古コピー機
大阪 デリヘル
大阪 デリヘル
大阪 デリヘル
日本語ラップ
日本語ラップ
MIX CD 通販
中古コピー機
中古コピー機
漫画 おすすめ マンガ
Paolo discount gucci shoes
Paolo discount gucci shoes have their own logo and are Paolo's one works in the current world of gucci women shoes. These watches are still recognized for the quality that has always been part of the Gucci name.
cheap uggs online nike
cheap uggs online
nike outlet
ugg outlet
ugg boots
ugg boots
ugg stores
Re
Sometimes different people have assignments to compose the politics essays related to this post. But a lot of them are inexperienced writers. Thus, what should they do under such circumstances? Some specialists instantly recommend to buy term paper in the online writing service.
ugg boots
Very grateful to God, so I saw this article, let me learn a lot.ugg boots saleonline,cheap uggs saleanduggs sale,Feeling very excited:ugg boots sale,gucci shoes,mbt shoes,cheap mbt shoes.Welcome to our site,thank you.
Ro Zeny
As a new player , you may need some game guides or information to enhance yourself.
Ro Zeny
is one of the hardest theme for every class at the beginning . You must have a good way to manage your Cheap Ro Zeny.If you are a lucky guy ,you can earn so many Ragnarok Zenyby yourself . But if you are a not , I just find a nice way to get Ragnarok Online Zeny. If you need , you can Buy Ro Zeny at our website . Go to the related page and check the detailed information . Once you have any question , you can connect our customer service at any time .
明石焼き ホームページ制作 駄菓子 いか焼 イギリス車
明石焼き ホームページ制作 駄菓子 いか焼 イギリス車 囲碁教室 居合道 工芸品 時計 産婦人科 美容整形 CFD 保険 リフォーム 結婚相談所 エステ 婚活 レンタルサーバー 探偵 税理士 不動産会社 看護師求人 インプラント システム開発 求人 SEO対策 風俗 風俗求人 FX 人気 転職 歯医者 自動車保険 高収入 証券会社 高校 ラーメン クレジットカード 太陽光発電 コスメ オンラインゲーム 企業 化粧品 就職 大学 ホームページ制作 オール電化 ホテル 歯医者 引越 歯医者 エステ 口コミ 探偵 結婚相談所 美容整形 エステ 病院 化粧品 コスメ 産婦人科 ダイエット 新築 静岡 原宿 ウェディング 広島 新築 広島 土地 広島 住宅 岡山 マンション 結婚情報サービス
栃木県 賃貸マンション 栃木県 奈良県 岐阜県 宮城県
栃木県 賃貸マンション 栃木県 奈良県 岐阜県 宮城県 群馬県 長野県 不動産賃貸 福島県 沖縄県 宮崎県 熊本県 鹿児島県 大分県 投資 山梨県 滋賀県 新潟県 新築マンション 石川県 富山県 和歌山 リフォーム 高知県 インテリア セクシーランジ ェリー 化粧品 外車 結婚指輪 ブランド品 滋賀県 アウトレット アメリカ アロマ あんみつ 海外旅行 甘味処 編物教室 足裏療法 収益物件 賃貸住宅 イギリス料理 コーチング 育児相談 家具 個人輸入 鯉 CDショップ コテージ ゴルフ ゴルフ会員権 ファッション 下着 SEO対策 アイスクリーム アウトドア アクセサリー 結婚式
葬儀場 質屋 リサイクルショップ 大学受験 グループホーム
葬儀場 質屋 リサイクルショップ 大学受験 グループホーム ブランド品 建設会社 動物病院 中学受験 税理士 株取引 レーシック 専門学校 派遣 携帯 ラブコスメ 予備校 小児科 旅行 旅館 ケータリング ホテル サイト売買 インプラント 弁護士 ナイキ わけあり ズワイガニ 通販 無添加化粧品 松山 土地 高知 土地 高松 土地 ナノコラーゲン アダルトグッズ通販 ダイエット茶 ペアリング通販 結婚相談所 インプラント 産婦人科 インプラント 病院 税理士 歯医者 自動車保険 クレジットカード 比較 お見合いパーティー 結婚式場 ケータリング 不動産会社 占い 探偵 学習塾 ネイルサロン 英会話 太陽光発電 老人ホーム 家庭教師 写真館 予備校 バイト 温泉 株 引越 大学受験 美容院 レーシック 中古車 質屋 小児科 ラブホテル
脱毛 永久脱毛 英会話 眼科 受験 学習塾 会計士
脱毛 永久脱毛 英会話 眼科 受験 学習塾 会計士 行政書士 法人設立 公認会計士 オフィス移転 結婚相談所 結婚式 結婚式場 婚活セミナー お見合い パーティー 出会い お見合いパーティー パーティー パーティードレス パーティー 出会いパーティー ウェディング ウエディング 結婚指輪 税理士 オークション 美容外科 美容院 探偵 ホテル 口腔外科 インプラント治療 広島インプラント インプラント インプラント大阪 インプラント 費用 インプラント東京 インプラント歯科 カタログ販売 家庭教師 幼稚園 弁護士 司法書士 受験 ラブホテル 学習塾 下着 バイク 介護施設 自転車 パーティー リフォーム カラオケボックス 設計事務所 ランジェリー 宗教団体 小児歯科 デイサービス
GHD hair straightener
thanks for sharing this nice post .ghd hair straightener always make you surprise
after you use it .just do as you like .
Chi flat iron, Chi Hair Straightener
well ,good article .chi hair iron in this season also make amazing by fashionable
people.make style with it .nice.
UGG Boots UK | Classic UGG Boots
this is a so nice post .ugg boots make this winter
so beautiful ,and we are attracted by many girls who wear
cardy ugg boots
on the street ,so fashion ,i am just thinking about it .
As the business grows,
As the business grows, replica rolex paypal has also jumped into an international brand. It is worth mentioning that, rolex replica is the ancestor of today's brand-oriented, in order to protect the quality and brand name will be printed on their products, the history of fashion in the world, is the first one first. replica watch paypal,replica watches paypal,fake rolex paypal.
Post new comment