linux系统编程之进程通信
生活随笔
收集整理的這篇文章主要介紹了
linux系统编程之进程通信
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、什么是進程線程?
進程通信:在用戶空間實現進程通信是不可能的,通過linux內核通信;
線程通信:可以在用戶空間就可以實現,可以通過全局變量通信。
進程間通信如下:
線程間通信如下:
二、進程間通信方式有哪些?
單機模式下的進程通信(只有一個linux內核)管道通信:無名管道、有名管道(文件系統中有名)信號通信:信號(通知)包括:信號的發送、信號的接收和信號的處理。IPC(Inter-Process Communication)通信:共享內存、消息隊列和信號燈。socket通信:存在于一個網絡中兩個進程之間的通信(兩個Linux內核)。進程間通信都是基于文件IO思想。
三、管道通信
1、無名管道(pipe)
2、有名管道 (mkfifo)–>管道文件(p)
所謂有名,即文件系統中存在這個一樣文件節點,每一個文件節點都有一個inode號, 而且這是一個特殊的文件類型:p 管道類型。 1、創建這個文件節點,不可以通過open函數創建,open函數只能創建普通文件,不能創建特殊的文件(管道-mkfifo,套接字-socket,字符設備文件-mknod,塊設備文件-mknod,符號鏈接文件-ln -s,目錄文件mkdir)2、管道文件只有inode號,不占磁盤塊空間,和套接字、字符設備文件、塊設備文件一樣。普通文件和符號鏈接文件及目錄文件,不僅有inode號,還占磁盤塊空間。3、mkfifo 用來創建管道文件的節點,沒有在內核中創建管道。只有通過open函數打開這個文件時才會在內核空間創建管道。 int mkfifo(const char *filename, mode_t mode); 創建管道文件 ---->sys.stat.h 參數:1)管道文件名;2)文件權限,與umask有關。 返回值:成功:0;失敗:-1。有名管道可以實現無親緣關系之間的進程通信。四、信道通信
1、信號的發送(發送信號進程)
int kill(pid_t pid, int sig); ---->#include <signal.h>、#include <sys/types.h>參數:1)pid,(linux shell查看進程號:ps -axj)正數:要接收的信號的進程的進程號;0:信號被發送到所有和pid進程在同一個進程組的進程;-1:信號發給所有的進程表中的進程(除了進程號最大的進程外)2)sig,信號(linux shell查看所有信號:kill -l)返回值:成功:0;失敗:-1。 int rasie(int sig); -----> #include <signal.h>、#include <sys/types.h>參數:sig,信號;返回值:成功:0;出錯:-1;發送信號給自己,相當于kill(getpid(), sig);注意:getpid() -->獲取當前進程的進程號;getppid() -->獲取當前進程的父進程的進程號。exit(0) --->包含kill(getppid(), 17); unsigned int alarm(unsigned int seconds); ---->#include <unistd.h>功能:alarm只會發送SIGALARM信號,alarm會讓內核定時一段時間之后發送信號,raise會讓內核立刻發送信號。參數:seconds,秒數;返回值:成功:如果調用此alarm()之前,進程已經設置了鬧鐘時間,則返回上一個鬧鐘時間的剩余時 間,否則返回0;出錯:-1;下面是幾種常見的信號:
SIGHUP :從終端上發出的結束信號.SIGINT :來自鍵盤的中斷信號 ( ctrl + c ) .SIGKILL :該信號結束接收信號的進程 .SIGTERM:kill 命令發出 的信號.SIGCHLD:標識子進程停止或結束的信號.SIGSTOP:來自鍵盤 ( ctrl + z ) 或調試程序的停止執行信號.2、信號的接收(接收信號進程)
接收信號的進程,需要滿足的條件為這個進程不能結束:sleep。pause():使進程處于睡眠狀態(S)。 int pause(void); ------>#include <unistd.h>返回值:成功:0;出錯:-1。3、信號的處理(接收信號進程)
接收信號的進程,應該怎樣處理?處理的方式: 1)進程的默認處理方式(內核為用戶進程設置的默認處理方式)A.忽略B.終止進程C.暫停 2)自己的處理方式:自己告訴內核自己需要處理信號的方式。 void (*signal(int signum, void(*handler)(int)))(int); ----->#include <signal.h>參數:1)signum,指定信號,信號值;2)handler:SIG_IGN:忽略該信號;SIG_DFL:采用系統默認方式處理信號;自定義的信號處理函數指針;返回值:成功:設置之前的信號處理方式;出錯:-1;五、IPC通信
1、共享內存
打開或創建一個共享內存對象,共享內核在內核是什么樣子? 一塊緩存,變類似于用戶空間的數組或malloc函數分配的空間一樣。| 函數原型 | int shmget(key_t key, int size, int shmflg); |
| 參數 | key:IPC_PRIVATE或ftok的返回值; |
| size:共享內存區大小; | |
| shmflg:同open函數的權限位,也可以用8進制表示法。 | |
| 返回值 | 成功:共享內存段標識符–ID–文件描述符;出錯:-1. |
shmat 將共享內存映射到用戶空間中,為了方便用戶空間對共享內存的操作,使用地址映射的方式。
void *shmat(int shmid, const void *shmaddr, int shmflg);參數:1)shmid,ID號2)映射到的地址,NULL為系統自動完成的映射;3)shmflg, SHM_RDONLY共享內存只讀默認是0,表示共享內存可讀寫。返回值:成功:映射后的地址;失敗:NULL。 共享內存特點:1、共享內存創建之后,一直存在于內核中,直到被刪除或系統關閉;2、共享內存和管道不一樣,讀取后,內容仍在共享內存中。 shmdt:將用戶空間的進程里的地址映射刪除。 int shmdt(const void *shmaddr);參數:shmaddr,共享內存映射后的地址返回值:成功:0;出錯:-1. shmctl:刪除共享內存對象。 int shmctl(int shmid, int cmd, struct shmid_ds *buf);參數:1)shmid,要操作的共享內存標識符。2)cmd: IPC_STAT(獲取對象屬性) ---->實現了ipcs -m命令IPC_SET(設置對象屬性)IPC_RMID(刪除對象) ---->實現了ipcrm -m命令3)buf:指定IPC_STAT/IPC_SET時用以保存或設置屬性返回值:成功:0;出錯:-1.六、消息隊列
msqid_ds 內核維護消息隊列的結構體,隊列的第一個消息指針msg_first,最后一個消息指針msg_last,消息中有一個成員指針next。
每一個消息中包含有哪些內容:
Data 數據
Length 數據的長度
Type 數據的類型
七、信號燈
所有的函數都是對一個集合的操作。
#include <sys/types.h>、#include <sy/sipc.h>、#include <sys/sem.h>
總結
以上是生活随笔為你收集整理的linux系统编程之进程通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【破解】PyCharm2018专业版激活
- 下一篇: undi是什么意思_undefined是