Linux訊號和命名管道

2021-07-28 02:13:00 字數 3704 閱讀 3767

概述:

在同一臺計算機中,程序相互通訊的方式主要有:管道(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,比...