I/O進程3
- day3
- 五、進程
- 7.函數接口
- 7.1創建子進程
- pid_t fork(void);
- 功能:創建子進程
- 返回值:成功:在父進程中:返回子進程的進程號 >0 ?在子進程中:返回值為0;? 失敗:-1并設置errno
- 特點
- 1.子進程幾乎拷貝了父進程的所有內容,包括代碼、數據,緩沖區,系統數據段中的值,棧中的數據,父進程打開的文件,但是PID,PPID不同
- 2.fork之前的代碼會被復制但是不會被重新執行,fork之后的代碼會被復制,并且父子進程分別執行一遍。
- 3.父子進程的空間相互獨立,互不影響,當在相應的進程中改變全局變量,靜態變量,都互不影響
- 4.fork之前打開的文件,fork之后拿到的是同一個文件描述符,操作的是同一個文件指針
- 5.若父進程先結束,子進程成為孤兒進程,被init進程所收養,會變成后臺進程。
- 6.若子進程先結束,父進程不結束,父進程沒有及時回收,子進程就會變成僵尸進程(避免僵尸進程的產生)
- 8.回收進程
- pid_t wait(int *status);
- 功能:回收子進程資源(阻塞)
- 參數:status:子進程退出狀態,不接受子進程狀態設為NULL
- 返回值:成功:回收的子進程的進程號 ? ? ? 失敗:-1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
- pid_t waitpid(pid_t pid, int *status, int options);
- 功能:回收子進程資源
- 參數:
- pid:>0 指定子進程進程號 ? ? ? ?=-1 任意子進程 ? ? ? ?=0 等待其組ID等于調用進程的組ID的任一子進程 ? ? ? ? ?<-1 等待其組ID等于pid的絕對值的任一子進程 ? ?
- status:子進程退出狀態 ? ?
- options:0:阻塞 ? ? ? ? ?WNOHANG:非阻塞
- 返回值:正常:結束的子進程的進程號 ? ? ?當使用選項WNOHANG且沒有子進程結束時:0 ? ? ? 出錯:-1
- 9.結束進程
- void exit(int status);
- 功能:結束進程,刷新緩存
- 參數:退出的狀態 不返回。
- 10.獲取進程號
- pid_t getpid(void);
- 功能:獲取當前進程的進程號
- pid_t getppid(void);
- 功能:獲取當前進程的父進程號
- 六、進程間通信
- 1.為什么要進行進程間通信
- 2.進程間通信方式(7)
- (1).早期進程間通信 無名管道(pipe)、有名管道(fifo)、信號(sem)
- (2).system V IPC通信 共享內存(share memory)、消息隊列(message queue)、信號燈集(semaphore)
- (3).BSD: 套接字(socket)
- 3.無名管道
- 3.1原理圖
-

- 通信原理:一個進程的輸出可以當作另一進程的輸入
- 3.2特點
- (1).只能用于具有親緣關系的進程間通信
- (2).半雙工通信模式,具有固定的讀端和寫端 {單工:只能單方向通信, 廣播 半雙工:可以雙向通信,但是同一時間不可以 對講機 全雙工:可以雙向同時通信 打電話}
- (3).無名管道可以被看做一個特殊的文件,對于他的讀寫可以使用文件IO函數 (注意:不是文件,他只是存在于內核空間的一部分,無實際文件)
- (4).管道基于文件描述符進行通信。當一個管道建立的時候,它會自動創建兩個文件描述符,一個用于讀fd[0],一個用于寫fd[1]。
- 3.3函數
- int pipe(int fd[2])
- 功能:創建無名管道
- 參數:文件描述符 fd[0]:讀端 fd[1]:寫端
- 返回值:成功 0 ? ? ? 失敗 -1
- 4.有名管道(FIFO)
- 4.1特點
- (1).可以使互不相干的兩個進程通信
- (2).有名管道可以通過路徑名來指出,并在文件系統中可見,但是內容存儲在內存中
- (3).進程通過文件IO操作有名管道
- (4).有名管道遵循先進先出的原則,不支持lseek()操作
- (5).半雙工通信
- 4.2函數
- int mkfifo(const char *filename,mode_t mode);
- 功能:創建有名管道
- 參數:filename:有名管道文件名 ? ? ? ?mode:權限
- 返回值:成功:0 ? ? ? ?失敗:-1,并設置errno號
- 七、信號
- 1.例子
- kill -l:查看系統中信號
- kill -num pid:給pid進程發送pid信號
- 2.概念
- (1).信號是在軟件層次上對中斷機制的一種模擬,是一種異步通信方式。 (2).信號可以直接進行用戶空間進程和內核進程之間的交互,內核進程也可以利用它來通知用戶空間進程發生了哪些系統事件。 (3).如果該進程當前并未處于執行態,則該信號就由內核保存起來,直到該進程恢復執行再傳遞給它;如果一個信號被進程設置為阻塞,則該信號的傳遞被延遲,直到其阻塞被取消時才被傳遞給進程。
- 3.信號響應方式
- (1.)忽略信號:對信號不做任何處理,但是有兩個信號不能做忽略處理:SIGKILL和SIGSTOP
- (2).捕捉信號:定義信號處理函數,當信號發生的時候,執行相應的處理函數,但是有兩個信號不能做捕捉處理:SIGKILL和SIGSTOP
- (3).執行缺省操作:linux對每種信號都規定了默認信號。
- 4.信號的種類
- 2)SIGINT:結束進程,對應快捷方式ctrl+c
- 3)SIGQUIT:退出信號,對應快捷方式ctrl+\
- 9)SIGKILL:結束進程,不能被忽略不能被捕捉
- 14)SIGALRM:鬧鐘信號,alarm函數設置定時,當到設定的時間時,內核會向進程發送此信號結束進程。
- 15)SIGTERM:結束終端進程,kill 使用時不加數字默認是此信號
- 17)SIGCHLD:子進程狀態改變時給父進程發的信號
- 19)SIGSTOP:暫停進程,不能被忽略不能被捕捉
- 20)SIGTSTP:暫停信號,對應快捷方式ctrl+z
- 信號的種類
- 在Linux中,信號被分為不可靠信號和可靠信號,一共64種,可以通過kill -l命令來查看
- ●不可靠信號:也稱為非實時信號,不支持排隊,信號可能會丟失,比如發送多次相同的信號,進程只能收到一次,信號值取值區間為1~31
- ●可靠信號:也稱為實時信號,支持排隊,信號不會丟失,發多少次,就可以收到多少次,信號值取值區間為32~64 信號產生的方式有如下幾種:
- ● 對于前臺進程,用戶可以輸入特殊終端字符來發送,比如輸入Ctrl+C
- ● 系統異常,比如浮點異常和非法內存段訪問
- ● 系統狀態變化,比如alarm定時器到期時將引起SIGALRM信號
- ● 在終端運行kill命令或在程序中調用kill函數
- 5.函數接口
- 5.1發送信號
- int kill(pid_t pid, int sig);
- 功能:信號發送
- 參數:pid:指定進程 ? ? ? ? ? sig:要發送的信號
- 返回值:成功 0?? ? ? ? ? ? ?失敗 -1? ? ?
- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
- ?int raise(int sig);
- 功能:進程向自己發送信號
- 參數:sig:信號
- 返回值:成功 0?? ? ? ? ? ? ?
- 失敗 -1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
- ??int pause(void);
- 功能:用于將調用進程掛起,直到收到信號為止。?
- 5.2定時器
- unsigned int alarm(unsigned int seconds)
- 功能:在進程中設置一個定時器
- 參數:seconds:定時時間,單位為秒
- 返回值:如果調用此alarm()前,進程中已經設置了鬧鐘時間,則 返回上一個鬧鐘時間的剩余時間,否則返回0。
- 注意:一個進程只能有一個鬧鐘時間。如果在調用alarm時 已設置過鬧鐘時間,則之前的鬧鐘時間被新值所代替
- 5.3信號處理
- #include <signal.h>
- typedef void (*sighandler_t)(int);
- sighandler_t signal(int signum, sighandler_t handler);
- 功能:信號處理函數
- 參數:
- signum:要處理的信號 ? ? ? ? ?
- handler:信號處理方式 ? ? ? ? ? ? ?
- SIG_IGN:忽略信號 ? ? ? ? ? ? ?
- SIG_DFL:執行默認操作 ? ? ? ? ? ? ?
- handler:捕捉信號 void handler(int sig){} //函數名可以自定義
- 返回值:成功:設置之前的信號處理方式 ? ? ? ? ? ? ?失敗:-1
- 八、共享內存
- 1.特點
- (1).共享內存是一種最為高效的進程間通信方式,進程可以直接讀寫內存,不需要進行任何數據的拷貝
- (2).為了在多個進程間進行數據的交互,內核專門留了一塊內存區,可以由需要訪問的進程將其映射到自己的地址空間
- (3).由于多個進程共享一段內存,因此也需要依靠某種同步機制,如互斥鎖和信號量等
- 2.編程步驟
- (1).創建或者打開共享內存shmget
- (2).映射共享內存到自己的用戶空間shmat
- (3).使用共享內存
- (4).撤銷映射
- (5).刪除共享內存
- 3.函數接口
- int shmget(key_t key, size_t size, int shmflg);
- 功能:創建或打開共享內存
- 參數: ? ? key 鍵值 ? ? size 共享內存的大小 ? ? shmflg IPC_CREAT|IPC_EXCL(判錯)|0666
- 返回值:成功 shmid ? ? ? ? ? ? ?出錯 -1
- void *shmat(int shmid,const void *shmaddr,int shmflg);
- 功能:映射共享內存,即把指定的共享內存映射到進程的地址空間用于訪問
- 參數: ? ?
- shmid 共享內存的id號 ? ?
- shmaddr 一般為NULL,表示由系統自動完成映射,如果不為NULL,那么由用戶指定 ? ?
- shmflg:SHM_RDONLY就是對該共享內存只進行讀操作? ,0 可讀可寫
- 返回值:成功:完成映射后的地址, ? ? ? 失敗:-1的地址
- 用法:if((p = (char *)shmat(shmid,NULL,0)) == (char *)-1)? ? ? ? ? ? ? ? ?
- ?int shmdt(const void *shmaddr);
- 功能:取消映射
- 參數:要取消的地址
- 返回值:成功0 ? ? ? 失敗的-1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
- int shmctl(int shmid,int cmd,struct shmid_ds *buf);
- 功能:(刪除共享內存),對共享內存進行各種操作
- 參數: ? ?
- shmid 共享內存的id號 ? ?
- cmd IPC_STAT 獲得shmid屬性信息,存放在第三參數 ? ? ? ? ? ?
- IPC_SET 設置shmid屬性信息,要設置的屬性放在第三參數 ? ? ? ? ? ?
- IPC_RMID:刪除共享內存,此時第三個參數為NULL即可
- 返回:成功0 ? ? ?失敗-1
- 用法:shmctl(shmid,IPC_RMID,NULL);
- 4.命令
- ipcs -m:查看系統中共享內存
- ipcrm -m shmid :刪除共享內存
本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/900583.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/900583.shtml
英文地址,請注明出處:http://en.pswp.cn/news/900583.shtml
如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!