久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Perl進(jìn)程(Processes)、管道(Pipes)和信號(hào)(Signals)之進(jìn)程

 vclyin 2012-04-20

本系列文章討論P(yáng)erl的三個(gè)關(guān)鍵功能:進(jìn)程(Processes),、管道(Pipes)信號(hào)(Signals),。通過建立一個(gè)新進(jìn)程,,Perl程序可以運(yùn)行另一個(gè)程序甚至是它自己的拷貝。管道允許Perl腳本剛其它進(jìn)行交換數(shù)據(jù),,而信號(hào)使Perl腳本監(jiān)視和控制其它進(jìn)程成為可能,。本文討論的是其中的:進(jìn)程。

進(jìn)程(Processes

UNIX,、VMS,、Windows NT/2000以及其它現(xiàn)代操作系統(tǒng)都是多任務(wù)的。它們能同時(shí)運(yùn)行多個(gè)程序,,每個(gè)程序運(yùn)行在獨(dú)立的線程運(yùn)行,,稱為進(jìn)程。在多核的電腦中,,進(jìn)程實(shí)際上是運(yùn)行在不同的CPU上同時(shí)運(yùn)行,。而在單核的電腦中,操作系統(tǒng)在多個(gè)進(jìn)程中快速切換,,每次執(zhí)行一小部分,,使進(jìn)程看上去是同時(shí)運(yùn)行的,

網(wǎng)絡(luò)應(yīng)用程序通過需要同時(shí)做兩個(gè)或兩個(gè)以上的事情,。例如,,服務(wù)器通常需要立刻處理客戶端的請(qǐng)求,與此同時(shí),,還需要監(jiān)視新的請(qǐng)求,。多任務(wù)大大簡(jiǎn)化了程序開發(fā),因?yàn)樗试S你為應(yīng)用程序所有操作啟動(dòng)新進(jìn)程,。幾乎每個(gè)進(jìn)程都是獨(dú)立的,,允許一個(gè)進(jìn)程繼續(xù)它的工作而不需要擔(dān)心它是干什么的。

Perl支持兩種多任務(wù),。一種基于傳統(tǒng)UNIX多重處理(multiprocessing)模式,,允許當(dāng)前進(jìn)程調(diào)用fork()函數(shù)克隆它自己。fork()執(zhí)行后,,將會(huì)有兩個(gè)各方面幾乎一致的進(jìn)程,。一個(gè)進(jìn)程執(zhí)行一個(gè)任務(wù),另一個(gè)執(zhí)行另一個(gè)任務(wù),。

另一種基于更現(xiàn)代的理念“線程(thread)”,,將所有任務(wù)放在一個(gè)進(jìn)程里面。無論如何,,單個(gè)程序可以有多個(gè)線程,,它們是相互獨(dú)立的。

本文將介紹fork()以及與進(jìn)程有關(guān)的變量和函數(shù),。我們將在以后的文章里討論多線程(multithreading ),。

fork()函數(shù)

fork()函數(shù)在所有的UNIX版本的Perl里有效,,以及VMS和OS/2。Perl 5.6(及更高版本的Perl)支持Microsoft Windows平臺(tái)的fork()函數(shù),,可惜的是,,不支持Macintosh。

Perl的fork()函數(shù)沒有參數(shù)并返回一個(gè)數(shù)字作為結(jié)果,。當(dāng)fork()被調(diào)用的時(shí)候,,它生成一個(gè)進(jìn)程的精確副本。這個(gè)副本稱為子進(jìn)程(child),,共享當(dāng)前的值和變量,,文件句柄(包含標(biāo)準(zhǔn)I/O緩存的數(shù)據(jù))以及其它數(shù)據(jù)結(jié)構(gòu)。事實(shí)上,,調(diào)用fork()的副本進(jìn)程都有一樣的內(nèi)存,。就好像科幻電影里演的一個(gè)人無意中走進(jìn)克隆出來的小房間里。

要保證和平共處,,必須清楚哪個(gè)是父進(jìn)程哪個(gè)是子進(jìn)程,。系統(tǒng)里所有的進(jìn)程都有一個(gè)唯一的正整數(shù),稱為進(jìn)程ID(process ID)或PID,。

調(diào)用fork()函數(shù)之后,,父進(jìn)程和子進(jìn)程判斷這個(gè)函數(shù)的返回值。在父進(jìn)程里,,fork()返回子進(jìn)程的PID。在子進(jìn)程里,,fork()返回?cái)?shù)字0,。根據(jù)這個(gè)返回值來判斷是否為父進(jìn)程。

$pid = fork()

創(chuàng)建一個(gè)新進(jìn)程,。在父進(jìn)程中返回子進(jìn)程的PID,,在子進(jìn)程中返回0。如果發(fā)生錯(cuò)誤(比如,,內(nèi)存不足)返回undef,,并將$!設(shè)為對(duì)應(yīng)的錯(cuò)誤信息

如果父進(jìn)程和子進(jìn)程想與其它進(jìn)程通訊,可借助管道(pipe)或者通過共用存儲(chǔ)器(shared memory),。父進(jìn)程和子進(jìn)程可以發(fā)送各自的PID給kill()函數(shù),。父進(jìn)程通過fork()函數(shù)的返回值來獲取子程序的PID,子進(jìn)程可以通過調(diào)用getppid()函數(shù)來獲得父進(jìn)程的PID,。進(jìn)程可以通過特殊的變量$$來獲得自己的PID,。

$pid = getppid()

返回父進(jìn)程的PID。每個(gè)Perl都有一個(gè)父進(jìn)程,,即使它通過命令行直接啟動(dòng)(此時(shí),,它的父進(jìn)程是shell進(jìn)程),。

$$

$$變量存儲(chǔ)著當(dāng)前進(jìn)程的PID。它是只讀的,。

kill()函數(shù)將在后面的“信號(hào)”一節(jié)進(jìn)行討論,。

正如你希望的那樣,一個(gè)子進(jìn)程也可以有它自己的 fork(),,創(chuàng)建一個(gè)孫進(jìn)程,。原來的父進(jìn)程可以再次 fork(),當(dāng)然它的子進(jìn)程和孫進(jìn)程也一樣可以,。這樣,,Perl腳本可以創(chuàng)建一批完整(而友好的,希望如此)的進(jìn)程,。除非明確操作,,這批進(jìn)程屬于同一個(gè)進(jìn)程組(process group)。

每個(gè)進(jìn)程組有一個(gè)唯一的ID,,通常與共同的祖先(第一個(gè)使用 fork()的進(jìn)程)的PID相同,。這個(gè)值可以通過 getpgrp()來獲得:

$processid = getpgrp([$pid])

如果指定了$pid, getpgrp() 函數(shù)返回對(duì)應(yīng)的組ID,。如果沒有指定PID,,返回當(dāng)前進(jìn)程所在的進(jìn)程組的ID。

進(jìn)程組中的每個(gè)成員共享所有從父進(jìn)程創(chuàng)建時(shí),,擁有的文件句柄,。特別是,共享 STDIN,、 STDOUT,。可以在任何子進(jìn)程中修改關(guān)閉文件句柄,,或者重新打開它,。系統(tǒng)一直保持跟蹤:子進(jìn)程打開文件句柄,但沒有關(guān)閉文件,。直到最后的子進(jìn)程時(shí),,關(guān)閉該文件句柄的拷貝。

#!/usr/bin/perl
#fork.pl - 創(chuàng)建單個(gè)的子進(jìn)程
##############################################
# (c) 2011 LoRui(i@, www.) #
##############################################

use strict;
use warnings;

print "PID = $$\n";

my $child = fork();
die "無法創(chuàng)建子進(jìn)程:$!" unless defined $child;

if($child > 0) { #父進(jìn)程
	print "父進(jìn)程:PID = $$, 子進(jìn)程 = $child\n";
} else { #子進(jìn)程
	my $ppid = getppid();
	print "子進(jìn)程:PID = $$, 父進(jìn)程 = $ppid\n";
}

通過檢查 $child 來確定,,我們的程序是以父進(jìn)程運(yùn)行還是子進(jìn)程,。如果 $child 非零,我們進(jìn)入父進(jìn)程處理:我們打印出了我們的PID和 $child 的內(nèi)容,,以及子進(jìn)程的PID,。

如果 $child 是零,那我們運(yùn)行在子進(jìn)程里,。我們通過調(diào)用 getppid()來獲取父進(jìn)程的PID,,并將其輸出,。

該代碼的執(zhí)行結(jié)果:

% fork.pl
PID=372
父進(jìn)程: PID=372, 子進(jìn)程=373
子進(jìn)程:  PID=373, 父進(jìn)程=372

注意,在Windows平臺(tái)運(yùn)行此腳本,,將會(huì)出現(xiàn)類似錯(cuò)誤:

The getppid function is unimplemented at fork.pl line 18.

原因在于,,Windows平臺(tái)的Perl并沒有實(shí)現(xiàn) getppid()函數(shù),請(qǐng)使用UNIX/Linux測(cè)試本代碼,。

system()exec()函數(shù)

在Perl啟動(dòng)子進(jìn)程的另一種方法是 system(),。system()將另一個(gè)程序作為子進(jìn)程運(yùn)行,等待其完成,,并返回結(jié)果,。如果成功, system()返回0(注意,,這和一般的Perl習(xí)慣不同,。【譯注:一般地,,在Perl(及其它類C語言)里,,0表示否定;非0表示肯定】),。如果子程序沒有啟動(dòng),,返回-1?;蛘叻祷仄渌e(cuò)誤代碼,。有關(guān)錯(cuò)誤代碼的完整解釋,請(qǐng)通過perlvar查看$?變量的詳細(xì)介紹,。

$status = system('command and arguments')
$status = system('command', 'and', 'arguments')

system()函數(shù)將命令(command)作為一個(gè)子進(jìn)程來執(zhí)行,,并等待它退出。該命令和它的參數(shù)(arguments)可以在單個(gè)字符串里指定,,也可以將它們作為列表的元素來指定。在第一種方式里,,字符串將完整無缺地傳遞給shell(【譯注:UNIX/Linux的shell,;Windows平臺(tái)的命令提示符(cmd.exe)】)。它允許你執(zhí)行包含shell元字符(shell metacharacters)(如輸入/輸出,,重定向),,但可能無意中執(zhí)行了shell命令。后一種方式允許你執(zhí)行帶有空白字符分隔的參數(shù),,shell元字符和其它特殊字符,,但不解析元字符。

exec()函數(shù)跟 system()很像,,但替換當(dāng)前進(jìn)程為指定的命令,。如果成功,,沒有任何返回值,因?yàn)檫M(jìn)程已經(jīng)結(jié)束,。新進(jìn)行將擁有與舊的那個(gè)同樣的PID,,并共享相同的 STDINSTDOUTSTDERR文件句柄,。無論如何,,其它已打開的文件句柄將自動(dòng)關(guān)閉。(你可以通過改變 $~F 變量的值來讓 exec()保持已打開的文件句柄,。詳細(xì)內(nèi)容請(qǐng)查看perlvar文檔,。)

$status = exec('command and arguments')
$status = exec('command', 'and', 'arguments')

exec()執(zhí)行一個(gè)命令,并替換當(dāng)前進(jìn)程,。只有出現(xiàn)錯(cuò)誤的時(shí)候,,它才返回狀態(tài)代碼。融不會(huì)返回任何結(jié)果,。單值形式和列表形式與 system() 的意思一樣,。

exec()通常與將一個(gè)命令作為子進(jìn)程運(yùn)行,處理完一些指定的步驟的fork()配合使用,。例子,,在上面fork.pl的代碼片段后面,子進(jìn)程在一個(gè)文件上重新打開 STDOUT,,然后調(diào)用 exec() 來運(yùn)行 ls -l 命令,。在UNIX系統(tǒng)上,這個(gè)命令獲取一個(gè)很長(zhǎng)的列表,。其效果是,,在后臺(tái)運(yùn)行 ls -l 命令,并將其輸出寫到指定的文件中,。代碼如下:

my $child = fork();
die "Can't fork: $!" unless defined $child;
if ($child == 0) { # we are in the child now
  open (STDOUT,">log.txt") or die "open() error: $!";
  exec ('ls','-l');
  die "exec error(): $!"; # shouldn't get here
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多