Linux編程:進程管理


本文內(nèi)容:
1. 進程產(chǎn)生方式
2. 進程間通信和同步
3. 線程


1. 進程產(chǎn)生方式

產(chǎn)生一個進程有多種方式仁热,如fork()香缺, system(), exec()函數(shù)等吱雏。

1.1 fork()

簡介

    #include <unistd.h>
    #include <sys/types.h>
    pid_t fork (void);

創(chuàng)建與當(dāng)前進程幾乎完全相同的子進程盹憎。
調(diào)用fork函數(shù)后筛峭,系統(tǒng)給新進程分配資源,例如存儲數(shù)據(jù)與代碼空間陪每,然后把原來進程的所有值都復(fù)制到新進程中影晓,只有少數(shù)的值與原進程不同。
fork()之后檩禾,子進程與父進程中的變量名相同挂签,但不共享,子進程或父進程中改變某變量的值不會影響另一個進程中相同名稱的變量值盼产。

  • 調(diào)用失敗返回小于0的值:
    errno=EAGAIN饵婆,當(dāng)前的進程數(shù)已經(jīng)達到系統(tǒng)上限。
    errno=ENOMEM,系統(tǒng)內(nèi)存不足戏售。
  • 調(diào)用成功返回兩個值:
    pid_t=0:子進程空間
    pid_t>0:父進程空間

調(diào)用成功后侨核,子進程和父進程都要執(zhí)行fork以后的語句,通過判斷fork的返回值來區(qū)分父進程和子進程灌灾。

fork()例程

#include <unistd.h>
#include <stdio.h>
int main(){
  pid_t fpid;
  int  count =0;
  fpid=fork();
  if(fpid<0)//調(diào)用失敗
    printf("error in fork!");
  else if(fpid==0) {  /子進程要執(zhí)行的部分
    printf("i am the child process,my pid is %d\n",getpid());
    count++;
  }
  else {  //父進程要執(zhí)行的部分
    printf("i am the parent process,my pid is %d\n",getpid());
    count++:
  }
  printf("count is:%d\n",count);
  return 0;
}

執(zhí)行過程:

image.png

執(zhí)行結(jié)果:
i am the child process,my pid is 3
count is 1
i am the parent process ,my pid is 2
count is 1
由于這兩個進程是獨立的搓译,存在于不同的地址空間,因此count變量不是共用的
參考:https://blog.csdn.net/jason314/article/details/5640969

1.2 system()

簡介
system()函數(shù)調(diào)用外部shell命令在當(dāng)前進程中開始另一個進程锋喜,阻塞當(dāng)前進程侥衬,直到外部命令執(zhí)行完畢。

#include <stdlob.h>
int system(const char command);
//command為需要執(zhí)行的外部命令

執(zhí)行system()函數(shù)時跑芳,會調(diào)用fork()轴总、 execve()、 waitpid()等函數(shù)博个,其中任意一個調(diào)用失敗將會導(dǎo)致system()調(diào)用失敗怀樟。
返回值:

  • 失敗:返回-1盆佣;
  • command不能執(zhí)行:返回127往堡;
  • 成功:返回進程狀態(tài)值。

system()例程

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
  int ret;
  printf("pid:%d \n",getpid());
  ret=system("mkdir test");
  printf("ret:%d \n",ret);
  return 0;
}

執(zhí)行結(jié)果:


image.png

當(dāng)前進程的ID為3368共耍,system()執(zhí)行“mkdir test”命令后返回值為0.
執(zhí)行結(jié)束后虑灰,當(dāng)前目錄下出現(xiàn)了新建的目錄test。

1.3 exec()

簡介
exec()族函數(shù)公有6個:

#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char const *envp[]);
int execve(const char *path, const char *arg[]);
int execvp(const char *path, const char *arg[]);

只有esecve()是真正的系統(tǒng)調(diào)用痹兜,其他都是此基礎(chǔ)上進行包裝的庫函數(shù)穆咐。
exec()函數(shù)族的作用是根據(jù)指定的文件名找到可執(zhí)行文件名,并在原來的進程內(nèi)部執(zhí)行此可執(zhí)行文件字旭。
exec()協(xié)議族調(diào)用成功不會返回对湃,失敗則會返回-1。
在Linux系統(tǒng)中遗淳,調(diào)用fork()之后進行exec()系統(tǒng)調(diào)用拍柒,系統(tǒng)就不會對父進程進行復(fù)制,而是直接使用exec()指定的參數(shù)覆蓋原有進程屈暗,利于節(jié)省時間拆讯。

exec()族成員函數(shù)介紹

  1. execl()
    #include <unistd.h>
    int execl(
      const char *path, //要執(zhí)行命令的路徑
      const char *arg, //要啟動程序所帶的參數(shù),一般第一個參數(shù)為要執(zhí)行的命令名
      .../* (char *) NULL */ //命令參數(shù)养叛,最后一個必須為NULL
    );

將當(dāng)前的進程替換成一個新的進程种呐,
執(zhí)行到exec()函數(shù)時當(dāng)前進程就會結(jié)束新進程則開始執(zhí)行。但新進程保留之前進程的進程號
執(zhí)行成功返回0一铅,失敗返回-1并設(shè)置errno信息
參考網(wǎng)站:https://www.cnblogs.com/mickole/p/3187409.html

  1. execlp()

  2. execle()

  3. execve()

  4. execvp()

2. 進程間通信和同步

消息隊列
msgrcv

include <sys/types.h>
include <sys/ipc.h>
include <sys/msg.h>
int msgrcv(
  int msgid,//消息隊列標識
  void *msgp,//存放消息的結(jié)構(gòu)體陕贮,類型要與msgsnd函數(shù)發(fā)送的類型相同
  size_t msgsz,//接受消息的大小,不含消息類型占用的4個字節(jié)
  long msgtyp;//接受類型
  int msgflg;//接受方式
);
//調(diào)用成功返回讀取到的消息長度潘飘,失敗返回錯誤碼
msgtyp的值 含義
0 接受第一個消息
>0 接受類型等于msgtyp的第一個消息
<0 接受類型等于或小于msgtyp絕對值的第一個消息
msgflg的值 含義
0 阻塞式肮之,沒有該類型的消息則一直等待
IPC_NOWAIT 如果沒有滿足條件的消息則立即返回,錯誤碼為ENOMSG
IPC_EXCEPT 與msgtyp配合是卜录,返回隊列中一地個類型不為msgtyp的消息
IPC_NOERROR 如果滿足條件的消息內(nèi)容大于size戈擒,則把消息截斷,截斷部分丟棄

解除阻塞的條件有三個:
1.消息隊列中有了滿足條件的消息
2.msgid代表的消息隊列被刪除
3.調(diào)用msgrcv的進程被信號中斷

錯誤碼 含義
E2BIG 消息長度大于size艰毒,而沒有設(shè)置IPC_NOERROR
EIDRM 標識為msgid的消息隊列已被刪除
EACCESS 沒有讀取權(quán)限
EFAULT msgp指向無效的內(nèi)存地址
ENOMSG msgflg為IPC_NOWAIT筐高,而隊列中無消息可讀
EINTR 等待讀取隊列的消息是被信號中斷

有關(guān)消息隊列的其他函數(shù)見:
https://blog.csdn.net/guoping16/article/details/6584024
waitpid

#include <sys/types.h>
#incude <sys/wait.h>
pid_t waitpid(
  pid_t pid,//進程ID
  int *status,//返回參數(shù)
  int options//調(diào)用選項
);

暫時停止目前進程的執(zhí)行,直到有信號到來或子進程結(jié)束。

  • pid
    pid>0 :只等待ID等于pid的子進程
    pid=0 :等待同一個進程組中的任何子進程
    pid=-1 :等待任何一個子進程退出
    pid<-1 :等待一個指定進程組中的任何子進程退出柑土,這個進程組的ID等于pid的絕對值

  • status
    返回子進程的結(jié)束狀態(tài)和進程識別碼蜀肘,可以設(shè)置為NULL

  • option
    option=0:不使用此功能
    option=WNOHANG:即使沒有子進程退出也會立即返回
    option=WUNTRACED:極少用
    信號
    kill

    include <sys/types.h>
    include <signal.h>
    int kill(//用于向任何進程或進程組發(fā)送信號
      pid_t pid,//進程號
      int sig//準備發(fā)送的信號代碼
    );
    

參考:https://www.cnblogs.com/leeming0222/articles/3994125.html
signal

#include <signal.h>
typedef void(*sighandler_t) int
sighandler_t signal(
  int signum,//要處理的信號類型,可以取除了SIGKILL和SIGSTOP外的任何一種信號
   sighandler_t handler//與信號關(guān)聯(lián)的動作
);

當(dāng)進程接收到類型為signal的信號時稽屏,不管程序執(zhí)行到那一部分扮宠,立即執(zhí)行handler動作。執(zhí)行結(jié)束后狐榔,控制權(quán)返回進程被中斷的一點繼續(xù)進行坛增。
參考:https://blog.csdn.net/yockie/article/details/51729774

#include <signal.h>
int sigempty(sigset_t *set);
//初始化set指向的信號集,清除其中的所有信號
int sigfillset(sigset_t *set);
//初始化set指向的信號集,使其包含所有信號
int sigaddset(sigset_t *set, int signo);
//在信號集中添加一個信號
int sigdeleset(sigset_t *set, int signo);
//在信號集中刪除一個信號
int sigismember(sigset_t *set, int signo);
//判斷某信號是否存在信號集中

參考:http://blog.sina.com.cn/s/blog_6f916d330100ycnh.html

3. 線程

參考文獻

  1. 《Linux網(wǎng)絡(luò)編程(第2版)》薄腻,宋敬彬等編著收捣。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市庵楷,隨后出現(xiàn)的幾起案子罢艾,更是在濱河造成了極大的恐慌,老刑警劉巖嫁乘,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昆婿,死亡現(xiàn)場離奇詭異,居然都是意外死亡蜓斧,警方通過查閱死者的電腦和手機仓蛆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挎春,“玉大人看疙,你說我怎么就攤上這事≈狈埽” “怎么了能庆?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脚线。 經(jīng)常有香客問我搁胆,道長,這世上最難降的妖魔是什么邮绿? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任渠旁,我火速辦了婚禮,結(jié)果婚禮上船逮,老公的妹妹穿的比我還像新娘顾腊。我一直安慰自己,他們只是感情好挖胃,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布杂靶。 她就那樣靜靜地躺著梆惯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吗垮。 梳的紋絲不亂的頭發(fā)上垛吗,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音抱既,去河邊找鬼职烧。 笑死,一個胖子當(dāng)著我的面吹牛防泵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝗敢,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼捷泞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寿谴?” 一聲冷哼從身側(cè)響起锁右,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讶泰,沒想到半個月后咏瑟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡痪署,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年码泞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狼犯。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡余寥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出悯森,到底是詐尸還是另有隱情宋舷,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布瓢姻,位于F島的核電站祝蝠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏幻碱。R本人自食惡果不足惜绎狭,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望收班。 院中可真熱鬧坟岔,春花似錦、人聲如沸摔桦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸥咖,卻和暖如春燕鸽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背啼辣。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工啊研, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸥拧。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓党远,卻偏偏與公主長得像,于是被迫代替她去往敵國和親富弦。 傳聞我的和親對象是個殘疾皇子沟娱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Linux 進程管理與程序開發(fā) 進程是Linux事務(wù)管理的基本單元,所有的進程均擁有自己獨立的處理環(huán)境和系統(tǒng)資源腕柜,...
    JamesPeng閱讀 2,451評論 1 14
  • 來源:IBM譯者:ljianhui鏈接:blog.csdn.net/ljianhui/article/detail...
    有文化_0a9b閱讀 635評論 0 1
  • 進程相關(guān)概念 內(nèi)核的功能 進程管理济似、文件系統(tǒng)、網(wǎng)絡(luò)功能盏缤、內(nèi)存管理砰蠢、驅(qū)動程序、安全功能等唉铜。 process 進程台舱,正...
    夾克K閱讀 1,000評論 0 1
  • 進程 1.基本描述 進程是處于執(zhí)行期的程序以及相關(guān)的資源總稱。 相關(guān)的資源:打開的文件打毛,掛起的信號柿赊,內(nèi)核內(nèi)部數(shù)據(jù),...
    MagicDong閱讀 489評論 0 0
  • 落日幻枉,余暉 他靜靜的坐在那碰声,臉朝著快要落山的太陽, 就這樣熬甫,不說話的沉默胰挑, 直到最后一絲陽光消失不見, 接著他費力...
    沉歡閱讀 446評論 5 6