概述:
在同一臺計算機中,程序相互通訊的方式主要有:管道(pipe)、訊號(signal)、訊號量(semaphore)、訊息佇列(message)和共享記憶體(shared memory)。訊號量、訊息佇列和共享記憶體稱為:ipc機制(inter process communication)
不同計算機之間的程序之間通訊可以使用套接字技術(socket)。
一、訊號
基本概念:
軟中斷訊號(signal,又簡稱為訊號)用來通知程序發生了非同步事件。程序之間可以互相通過系統呼叫kill傳送軟中斷訊號。核心也可以因為內部事件而給程序傳送訊號,通知程序發生了某個事件。注意,訊號只是用來通知某程序發生了什麼事件,並不給該程序傳遞任何資料。
訊號是程序間通訊機制唯一的非同步通訊機制。乙個程序不必通過任何操作等待訊號的到達。使用kill命令來結束程序就是通過訊號實現的。
常用訊號及解釋:
訊號名稱
訊號值解釋
sighup
1由於終端掛起或者控制程序終止而發出的訊號
sigint
2一般由鍵盤按鍵產生的中斷訊號,比如按下ctrl+c組合鍵
sigquit
3一般由鍵盤的退出鍵被按下而產生的結束訊號。比如ctrl+\組合鍵
sigill
4非法指令
sigabrt
6由abort()函式發出的退出指令,收到sigabrt訊號,說 明檢測出程式是有問題。
sigkill
9不能**捉或忽略的資訊,一般用來強行結束異常程序
sigusr1
10使用者自定義訊號1,程序可以使用這個訊號進行通訊
sigsegv
11記憶體引用無效
sigchld
17子程序結束訊號……
… 訊號處理的具體函式:
#include /*******
* 用法:signal(signum訊號型別, 函式控制代碼);
* 在呼叫中,引數signum指出要設定處理方法的訊號。或者是
* sig_ign(忽略引數signum所指的訊號)
* sig_dfl(恢復引數signum所指訊號的處理方法為預設值)
*/void (*signal(int sig, void (*func)(int)))(int);
/*******
* 用法:sigaction(要檢測或修改其具體動作的訊號, 指向sigaction的乙個例項指標, 指向物件用來儲存原來對相應訊號的處理,可指定oldact為null)
* 檢查和改變乙個行動的訊號
*/int sigaction(int sig, const struct sigaction *restrict act, struct sigaction *restrict oact);
程式實現:
#include
#include
#include
#include
void signalhandle(int
signal)
}int main()
二、管道管道:指程序直接進行資料交換的通道,可分為普通管道(pipe)和命名管道(fifo)。通過核心緩衝區按先進先出的方式進行資料傳輸。管道一端順序地寫入資料,另一端順序地讀入資料。管道是半雙工,資料只能向乙個方向流動;要雙方通訊時需要建立兩個管道。
對命名管道操作與檔案操作相似。
一般使用mkfifo()函式建立命名管道檔案,函式定義如下:
/*******
* 引數一pathname:是檔案路徑名稱
* 引數二mode:開啟普通檔案的open()函式中的mode
*/int mkfifo(const
char *pathname,mode_t mode);
開啟方式
tables
areo_rdonly
唯讀方式開啟
o_wronly
只寫方式開啟
o_rdonly | o_nonblock
唯讀且非阻塞的方式開啟
o_ wronly | o_nonblock
唯讀且非阻塞的方式開啟
注意: pipe_buf值 對應標頭檔案 limits.h。資料長度不能大於管道緩衝區長度,一般為4096。
**實現:
// 傳送部分
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fifo_handle_name "/tmp/fifo_handle "
#define fifo_client_name "/tmp/fifo_client_%d"
struct ps_fifo_struct;
int main ()
ps_fifo.pid = getpid();
memset(client_fifo_name, 0, 64);
sprintf(client_fifo_name, fifo_client_name, ps_fifo.pid);
if(access(client_fifo_name,f_ok) == -1)
}sprintf(ps_fifo.str, "hello i am %d.", ps_fifo.pid);
printf("%d sent:\'%s\'. \n", ps_fifo.pid, ps_fifo.str);
write(fifo_handle, &ps_fifo, sizeof(ps_fifo));
fifo_client = open(client_fifo_name, o_rdonly);
if(fifo_client != -1)
}close(fifo_handle);
unlink(client_fifo_name);
exit(exit_success);
return
0;}
// 接收部分
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fifo_handle_name "/tmp/fifo_handle "
#define fifo_client_name "/tmp/fifo_client_%d"
struct ps_fifo_strcut
;int main()
}fifo_handle = open(fifo_handle_name, o_rdonly);
if (fifo_handle == -1)do}
} while (/*read_len > 0*/
1); close(fifo_handle);
unlink(fifo_handle_name);
exit(exit_success);
return
0;}
linux的管道和命名管道
看了個教程,感覺還是要結合 看。管道是linux裡面程序間通訊的一種方式,其他的還有像訊號 signal 訊號量 訊息佇列 共享記憶體 套接字 socket 等。1.管道pipe int pipe int fd 2 返回值 成功,返回0,否則返回 1。引數陣列包含pipe使用的兩個檔案的描述符。fd...
linux中匿名管道和命名管道
1 建立管道和父子程序,子程序關閉讀端,父程序關閉寫端,子程序寫,父程序讀。2 如果所有指向管道寫端的檔案描述符都關閉了 管道寫端的引用計數等於0 而仍然有程序 從管道的讀端讀資料,那麼管道中剩餘的資料都被讀取後,再次read會返回0,就像讀到檔案末尾一樣。3 如果有指向管道寫端的檔案描述符沒關閉 ...
Linux命名管道
命名管道實現了沒有親緣關係的程序的通訊,建立命名管道時候,系統建立了乙個fifo的檔案,通過對檔案的操作,實現走了沒有親緣關係的管道也可以資料交換,相比普通管道 命名管道多了管道的開啟和刪除,因為是檔案嗎,當然劇本檔案的屬性了。1.可以通過該shell命令建立命名管道,mknod 和mkfifo,比...