linux 多程序程式設計詳解

2021-08-26 09:33:36 字數 4848 閱讀 8286

#include

#include

pid_t fork( void);
pid_t 是乙個巨集定義,其實質是int 被定義在#include

若成功呼叫一次則返回兩個值,子程序返回0,父程序返回子程序id;否則,出錯返回-1

也用於建立乙個程序,返回值與fork()相同。

fork()與vfork()的異同

建立子程序之後,子程序拷貝了父程序所有的變數,並且子程序修改變數的值,並不影響父程序的變數值。

fork()的返回值不同。

程序id不同

#include 

#include

#include

#include

#include

#include

#include

using

namespace

std;

// 程序退出函式

void print_exit()

int main()

}if(pid == -1)

else

if(pid == 0)

else

printf("i am main progress.the pid progress has not exited!\n");

sleep(2);

}while(child_pid == 0);

exit(0);

}return

0;}

執行結果

#include 

#include

main ()

這裡可以看出parent process執行了printf(「hello!\n」); 而child process 沒有執行printf(「hello!\n」);

有乙個讓人很迷惑的例子:

#include 

#include

main ()

此時列印輸出了兩個fork!這不免讓人以為是child process從#include處開始執行,所以也執行了printf(「fork!」); 語句。

其實不然,出現這種問題的原因在於:

這就跟printf的緩衝機制有關了,printf某些內容時,作業系統僅僅是把該內容放到了stdout的緩衝佇列裡了,並沒有實際的寫到螢幕上 。但是,只要看到有\n, 則會立即重新整理stdout,因此就馬上能夠列印了.mian函式(parent process)執行了printf(「fork!」) 後, 「fork!」僅僅被放到了緩衝裡,再執行到fork時,緩衝裡面的 aaaaaa 被子程序(child process)繼承了,因此在子進程度stdout緩衝裡面就也有了」fork!」。所以,你最終看到的會是 「fork!」 被printf了2次!!!! 而mian函式(parent process)執行 printf(「fork!\n」)後,」fork!」 被立即列印到了螢幕上,之後fork到的子程序(child process)裡的stdout緩衝裡不會有」fork!」內容 因此你看到的結果會是」fork!」 被printf了1次!!!!

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

struct task_list_

task_list;

void print_exit()

task_list tasklist[5];

#define size 1024

const

long id = 1;

int main(int argc, char

const *argv)

sndmsg, rcvmsg;

task_list smatch;

pid_t pid, child_pid;

//int status;

vector

provlist;

tasklist[0].taskinfo = "1001";

tasklist[1].taskinfo = "2002";

tasklist[2].taskinfo = "3003";

tasklist[3].taskinfo = "4004";

tasklist[4].taskinfo = "5005";

for (int i = 0; i < 5; i++)

cout

<<"main process,id="

// ipc_creat :建立乙個訊息佇列 ipc_excl :如果已經存在則報錯

msgid = msgget(unique_key,ipc_creat | ipc_excl);

for (int i = 0; i < provlist.size(); i++)

}if(pid == -1)

else

if(pid == 0)

int taskid = atoi(rcvmsg.msgtext);

if(taskid == 1)

printf("the received message is:%s\n", rcvmsg.msgtext);

// msgctl(msgid, ipc_rmid, 0); // delete the message queue

//這裡寫子程序處理邏輯

cout

<< "this is children process,id="

<< getpid() << endl;

sleep(2);

exit(0);

}else

}// 這裡主程序處理邏輯

// do

// // printf("i am main progress.the pid progress has not exited!\n");

// sleep(2);

// }while(child_pid == 0);

// exit(0);

}return

0;}

該函式用來建立和訪問乙個訊息佇列

int msgget(key_t, key, int msg***);

與其他的ipc機制一樣,程式必須提供乙個鍵來命名某個特定的訊息佇列。msg***是乙個許可權標誌,表示訊息佇列的訪問許可權,它與檔案的訪問許可權一樣。msg***可以與ipc_creat做或操作,表示當key所命名的訊息佇列不存在時建立乙個訊息佇列,如果key所命名的訊息佇列存在時,ipc_creat標誌會被忽略,而只返回乙個識別符號,它返回乙個以key命名的訊息佇列的識別符號(非零整數),失敗時返回-1.

該函式用來把訊息新增到訊息佇列中。

int msgsend(int msgid, const

void *msg_ptr, size_t msg_sz, int msg***);

msgid是由msgget函式返回的訊息佇列識別符號。

msg_ptr是乙個指向準備傳送訊息的指標,但是訊息的資料結構卻有一定的要求,指標msg_ptr所指向的訊息結構一定要是以乙個長整型成員變數開始的結構體,接收函式將用這個成員來確定訊息的型別。所以訊息結構要定義成這樣:

struct my_message

;

msg_sz是msg_ptr指向的訊息的長度,注意是訊息的長度,而不是整個結構體的長度,也就是說msg_sz是不包括長整型訊息型別成員變數的長度。

msg***用於控制當前訊息佇列滿或佇列訊息到達系統範圍的限制時將要發生的事情。

如果呼叫成功,訊息資料的一分副本將被放到訊息佇列中,並返回0,失敗時返回-1.

該函式用來從乙個訊息佇列獲取訊息,它的原型為

int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msg***);

msgid, msg_ptr, msg_st的作用也函式msgsnd函式的一樣。

msgtype可以實現一種簡單的接收優先順序。如果msgtype為0,就獲取佇列中的第乙個訊息。如果它的值大於零,將獲取具有相同訊息型別的第乙個資訊。如果它小於零,就獲取型別等於或小於msgtype的絕對值的第乙個訊息。

msg***用於控制當佇列中沒有相應型別的訊息可以接收時將發生的事情。

呼叫成功時,該函式返回放到接收快取區中的位元組數,訊息被複製到由msg_ptr指向的使用者分配的快取區中,然後刪除訊息佇列中的對應訊息。失敗時返回-1.

該函式用來控制訊息佇列,它與共享記憶體的shmctl函式相似,它的原型為:

int msgctl(int msgid, int command, struct msgid_ds *buf);

command是將要採取的動作,它可以取3個值,

ipc_stat:把msgid_ds結構中的資料設定為訊息佇列的當前關聯值,即用訊息佇列的當前關聯值覆蓋msgid_ds的值。

ipc_set:如果程序有足夠的許可權,就把訊息列隊的當前關聯值設定為msgid_ds結構中給出的值

ipc_rmid:刪除訊息佇列

buf是指向msgid_ds結構的指標,它指向訊息佇列模式和訪問許可權的結構。msgid_ds結構至少包括以下成員:

struct msgid_ds

;

成功時返回0,失敗時返回-1.

linux多程序程式設計

在linux中,執行的乙個程序,會占去linux的三個地方,區,堆疊區和資料區.如果同時執行多個相同的程式,他們就會使用相同的 區,區中存放的就程式的 但是資料區和堆疊區分別存放的是程式的資料,全域性變數和區域性變數,因此即使是相同的程式,也不可同時使用相同的資料和堆疊區.include inclu...

linux 多程序程式設計基礎

一 linux下程序的理解 linux環境下乙個程序在記憶體中有三部分資料 資料段 堆疊段和 段 段 就是存放程式 的資料,如果有數個程序執行乙個程式,那麼他們就可以使用同乙個 段 堆疊段 存放的是子程式的返回位址 引數以及程式的區域性變數 資料段 存放程式的全域性變數 常數以及動態資料分配的資料空...

linux多程序c程式設計

多程序程式設計 今天覆習了多程序程式設計,共涉及只是大致有程序的建立於結束,退出,終止,等待,休眠,獲取程序號,執行外部的應用程式等的函式使用,還了了解程序與執行緒的區別於相同之處,在此對於pid,ppid,pigid,puid等獲取方式與相關表示就不在陳述,建立程序的兩個主要函式vfork與for...