1. 程式人生 > >Linux 程序通訊之 ——訊號和訊號量總結

Linux 程序通訊之 ——訊號和訊號量總結

現在最常用的程序間通訊的方式有:訊號,訊號量,訊息佇列,共享記憶體。 
      所謂程序通訊,就是不同程序之間進行一些"接觸",這種接觸有簡單,也有複雜。機制不同,複雜度也不一樣。通訊是一個廣義上的意義,不僅僅指傳遞一些massege。他們的使用方法是基本相同的,所以只要掌握了一種的使用方法,然後記住其他的使用方法就可以了。 

      1. 訊號 
      在我學習的內容中,主要接觸了訊號來實現同步的機制,據說訊號也可以用來做其它的事
      情,但是我還不知道做什麼。 
      訊號和訊號量是不同的,他們雖然都可用來實現同步和互斥,但前者是使用訊號處理器來
      進行的,後者是使用P,V*作來實現的。 

      使用訊號要先知道有哪些訊號,在Linux下有31個需要記住的通用訊號,據說也是system
      V中最常用的那些。這裡略。 
      1. 1訊號相關函式: 
      #include 
      int sigaction(int signo, const struct sigaction *act, struct sigaction
      *oact); 
      該函式用來為程序安裝訊號處理器,struct sigaction資料是用來儲存訊號處理器的相
      關資訊。 

      #include 
      int sigemptyset(sigset_t *set); 

      將訊號集合清空。 
      int sigfillset(sigset_t *set); 
      將訊號集合設定成包含所有的訊號。在對訊號進行*作以前一定要對訊號集進行初始化。

      int sigaddset(sigset_t *set, int signo); 
      向訊號集中加入signo對應的新訊號。 
      int sigdelset(sigset_t *set, int signo); 
      從訊號集中刪除signo對應的一個訊號。 
      int sigismember(const sigset_t *set, int signo); 
      判斷某個訊號是否在訊號集中。返回1則在,0則不在。 


      #include 
      int sigprocmask(int how,const sigset_t *set, sigset_t *oset); 
      用來設定程序的訊號遮蔽碼。訊號遮蔽碼可以用來在某段時間內阻塞一些訊號集中的信
      號,如果訊號不在訊號集中,就不必討論它,因為肯定不響應,是否能生成也不肯定,我
      沒有做過試驗。 

      1.2我所理解的使用訊號機制的方法: 
      使用訊號,主要做的事情就是訊號處理器的工作,這裡面是你想做的事情。就像中斷處理
      函式一樣。 
      在使用訊號以前,首先要初始化訊號集,只有在訊號集裡面的訊號才會被考慮。 
      有兩種方法可以初始化訊號集,一種是設定空訊號集,一種是將所有的訊號都加到訊號集
      中。如果你自己想要的訊號集不是這兩種,可以在初始化了以後通過新增和刪除訊號進行
      定製。 
      如果在程序執行的一段時間內不想對某些訊號進行響應,則可以使用sigprocmask對當前
      的訊號集中的一些訊號進行阻塞,稍後再執行。 
      當你將訊號集設定完畢後,在讓他工作之前需要安裝訊號處理器。安裝訊號處理器可以實
      現這幾個功能: 
      指定訊號處理函式的入口;指定訊號遮蔽集合;指定訊號處理器的一些標誌。所謂訊號處
      理器,就是指定了一些處理方法,關鍵在於安裝訊號處理器,這是使正確的訊號進行正確
      的處理關鍵。在安裝的時候,一定要對特定的訊號賦予正確的訊號處理函式。 
      我不知道不同程序之間的訊號處理器能否混用,但是像一個特定的程序中有多少個訊號處
      理器這樣的問題是不能提的。因為訊號處理器是一個概念,他針對的是訊號,就是說如果
      你指定了一個資料結構,用它來儲存針對某個訊號的處理資訊,那麼安裝訊號處理器就是
      賦予這個資料結構一些相關資訊,使用訊號處理器就是用這個資料結構儲存的資訊來組織
      一種機制當發生這個訊號的時候會做一些你實現設定好的處理。但是如果區分不同程序中
      對同一個訊號的不同處理器?我想處理器可能只對核它所屬的程序有關的訊號進行響應,
      但是如果是這樣的話,那這是怎麼實現的呢? 
      不過有一點是可以知道的,那就是每一個訊號都有一個訊號處理器(確定的),可以動過
      安裝訊號處理器來指定她的行為。訊號處理器由他自己的資訊儲存區域(我不知道在什麼
      地方),但是可以通過向sigaction型別的資料結構向訊號處理器的資訊儲存區域中傳遞
      資訊。這個資料結構由一個就可以了,因為它只是臨時傳遞資料的載體。 
      但是sigpromask和訊號處理器裡面的sigmask是不一樣的,前者是在程序當前流程設定信
      號遮蔽,後者是指定在訊號處理器作用時需要遮蔽掉的訊號。例如,在設定某個特定訊號
      的訊號處理器時,我們當然不能讓它的訊號處理器工作了,因為還沒有設定完嗎,這是我
      們可以使用sigprocmask來讓當前的流程開始阻塞該訊號,當設定完訊號處理器以後,再
      用sigprocmask恢復被阻塞的訊號。而以後再接收到該訊號時,訊號處理器就可以工作了。 
      我的想法是,同一個訊號在不同的程序裡可以有不同的訊號處理器(一般應該有一個預設
      處理),當系統中發生一個訊號時,所有能接受到的程序都可以接收到這個訊號,並用他
      們自己的訊號處理器對這個訊號做出各自的響應。 

      1.3如何用訊號來進行程序間的同步 
      同步的實現主要是通過在接受訊號之前掛起程序,等待相關訊號。所以涉及到非同步訊號安
      全函式的概念。 

      不過訊號如何來實現程序間的互斥,我理解不是很多,我想訊號的主要用處還是在軟中斷
      處理和程序同步。 


      2.訊號量 
      訊號量和訊號是不同的東西,仔細想想就可以理解:訊號是實現約定的固定的值,而訊號
      量是一個變數記錄著某些特定資訊。 
      訊號量這種東西我們在*作系統課程中就已經接觸過了,這裡只是再草草說幾句。訊號量
      分為有名和無名兩種。程序間通訊用有名訊號量,同一程序內部通訊一般用無名訊號量。
      這個我不再多說。 
      2.1訊號量相關函式 
      #include 
      #include 
      #include 
      int semget(key_t key, int nsems, int semflg); 
      建立一個新的訊號量組或獲取一個已經存在的訊號量組。 

      #include 
      #include 
      #include 
      int semop(int semid, struct sembuf *sop, int nsops); 
      semop函式可以一次對一個或多個訊號量進行*作。 
      Int semctl(int sem_id, int semnum, int cmd,/*union semun arg*/…); 
      該函式可以用來獲取一些訊號量的使用資訊或者是來對訊號量進行控制。 

      2.2我對訊號量機制的理解 
      對訊號量的*作只有兩個:P, V。 
      為了在邏輯上便於組織訊號量,訊號量機制中有一個概念是訊號量組。我們可以把一個信
      號量組中建立相關的訊號量,這樣邏輯上清晰也便於管理。在使用之前你同樣需要對他們
      進行初始化:生成或開啟訊號量組,向其中生成或刪除你指定的訊號量。 
      對訊號量的*作只用兩種,他都是通過semop函式中的sops引數來指定的,如果這個引數
      是一個數組的話,那麼就是對多個訊號量進行*作。Sops引數中的sem_op欄位指明瞭對信
      號量進行的是P*作還是V*作。你只要指定就行了,具體的*作不需要你去實現,函式中
      都已經提供了。使用訊號量,你得清楚訊號量組id和訊號量在訊號量組中的位置(其實也
      就是另一個id)。一個訊號量必須屬於一個訊號量組,否則不能被系統所使用。切記! 
      訊號量和訊號量組是不會被系統所自動清理的,所以當你的程序退出前,千萬別忘了清理
      你生成的那些訊號量們。 
      訊號量既可以實現互斥,也可以實現同步,這裡就不說了,*作系統課程中是有介紹的。



      3.訊息佇列 
      訊息佇列是比較高階的一種程序間通訊方法,因為它真的可以在程序間傳送massege,你
      傳送一個"I seek you"都可以。 
      一個訊息佇列可以被多個程序所共享(IPC就是在這個基礎上進行的);如果一個程序的
      訊息太多一個訊息佇列放不下,也可以用多於一個的訊息佇列(不過可能管理會比較復
      雜)。共享訊息佇列的程序所傳送的訊息中除了massege本身外還有一個標誌,這個標誌
      可以指明該訊息將由哪個程序或者是哪類程序接受。每一個共享訊息佇列的程序針對這個
      佇列也有自己的標誌,可以用來宣告自己的身份。 
      對於系統中的每一個訊息佇列,都有一個數據結構來代表它,這個資料結構是msqid_ds,
      這裡略去不講,在中可以看到它的原型。 

      3.1訊息佇列相關函式 
      使用訊息佇列之前,你要麼獲得這個訊息佇列,要麼自己建立一個,否則是不能使用訊息
      佇列的(我覺得這都像是多餘的話,請見諒)。當這個訊息佇列不再使用時,也一定要有
      一個程序來刪除訊息佇列,系統是不會自動的清理訊息佇列和msgid_ds的。 

      Int msgget(key_t key, int msgflg); 
      獲取一個存在的訊息佇列的ID,或者是根據跟定的許可權建立一個訊息佇列。但是怎麼樣去
      刪除這個訊息佇列,我還不十分清楚。 
      Int msgctl(int msqid, int cmd, struct msqid_ds *buf); 
      用來從msqid_ds中獲取很多訊息佇列本身的資訊。 
      Int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg); 
      用於向佇列傳送訊息。 
      Int msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, int
      msgflg); 
      從佇列中接收訊息。 
      我這個文件裡面對訊息佇列中的一些臨界情況所述不多,因為這是我的小結,而非介紹。
      在GNU C庫技術中可以看到它的詳細介紹。

相關推薦

linux程序通訊訊號燈(訊號,semaphore)

訊號燈通訊,和一般意義的通訊不大一樣,通訊一般是用來收發資料,而訊號燈卻是用來控制多程序訪問共享資源的,利用這一功能,訊號量也就可以用做程序同步(實際上是執行緒間同步)。訊號燈的當前值、有幾個程序在等待當前值變為0等等,這些資訊,可隨時用watch -n 0.1 ipcs -

Linux程序通訊管道FIFO

Linux程序間的通訊可以簡稱為IPC(Interprocess Communication),前面說過的 Linux的同步工具也是屬於IPC的一部分,這裡我想說的是通常意義的程序間的實際資料通。 1管道 管道是最早的UNIX IPC,所有的UNIX系統都支援這個IPC通訊機制。我們最常見到使用它的位置就是

Linux 程序通訊 ——訊號訊號總結

現在最常用的程序間通訊的方式有:訊號,訊號量,訊息佇列,共享記憶體。       所謂程序通訊,就是不同程序之間進行一些"接觸",這種接觸有簡單,也有複雜。機制不同,複雜度也不一樣。通訊是一個廣義上的意義,不僅僅指傳遞一些massege。他們的使用方法是基本相同的,所以只要

Linux程序通訊訊號

文章轉自   http://blog.csdn.net/maimang1001/article/details/16906451 鑑於後面把程序的形象給徹底毀掉了,我提前宣告一下,程序是有尊嚴的有節操的,當然大部分人可能也看不到毀形象那一段。為什麼介紹linux要從訊號

Linux 程序通訊:記憶體共享(Shared Memory)

一、簡介 共享記憶體允許兩個程序訪問同一塊記憶體區域,它們使用同一個 key 值標記。 二、特點 優點: 通訊方便,兩個程序也是直接訪問同一塊記憶體區域,減少了資料複製的操作,速度上也有明顯優勢。 缺點: 沒有提供同步機制,往往需要我們使用其它(例如訊號)等手段實

Linux 程序通訊:管道 (Pipe)

一、簡介 管道(pipe) 是一種最基本的 IPC(Inter Process Communication) 機制,優點是簡單。 二、特點: 管道只適用於 存在血緣關係 的兩個程序之間通訊,因為只有存在血緣關係的兩個程序之間才能共享檔案描述符 管道分為兩端,一端

Linux 程序通訊:記憶體對映(Memory Map)

一、簡介 正如其名(Memory Map),mmap 可以將某個裝置或者檔案對映到應用程序的記憶體空間中。通過直接的記憶體操作即可完成對裝置或檔案的讀寫。. 通過對映同一塊實體記憶體,來實現共享記憶體,完成程序間的通訊。由於減少了資料複製的次數,一定程度上提高了程序間通訊的效率。

Linux 程序通訊:命名管道 (FIFO)

一、簡介 由於管道(Pipe)只能應用於存在血緣關係的程序間通訊,為了突破這個限制,使用命名管道(FIFO)來實現 不相干程序間 的通訊。 FIFO 是 Linux 基礎檔案型別中的一種,它並不佔用磁碟上實際的資料塊,而僅僅是標識核心中的一條通道。各程序可以開啟

Linux 程序通訊 命名管道

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> int main() { int fb =

Linux程序通訊訊息佇列的雙向通訊

  上一篇部落格我寫了程序間通訊基於管道的通訊,但是管道的通訊無疑有很大的缺點,最顯著的就是隻能單向通訊,例如:server向client發訊息,client無法回覆;第二個就是隻能在有血緣關係的程序間進行通訊,雖然命名管道解決了第二點,但是第一點還是一個很大的

Linux 學習筆記—程序通訊 訊息佇列、訊號、共享記憶體的概念區別聯絡

2.5 訊息佇列(Message queues) 訊息佇列是核心地址空間中的內部連結串列,通過linux核心在各個程序直接傳遞內容,訊息順序地傳送到訊息佇列中,並以幾種不同的方式從佇列中獲得,每個訊息佇列可以用IPC識別符號唯一地進行識別。核心中的訊息佇列是通過

linux系統——IPC程序通訊訊號

一、訊號量引出 當我們編寫的程式使用執行緒的時候,總是有一部分臨街程式碼,需要確保只有一個程序(或一個執行緒)可以進入這個臨街程式碼並擁有對資源的獨佔式訪問 ——》檔案鎖,提供了一個原子化的檔案建立方法,它允許一個程序通過一個令牌(新建立的檔案)來取得成功,這個

Linux程序通訊——訊號

https://blog.csdn.net/a1414345/article/details/64513946 對於上文中程式碼的cmake編寫 目錄       mysem             &

linux程序控制訊號 semget,semctl,semop

轉載自 https://www.cnblogs.com/52php/p/5851570.html 這篇文章將講述別一種程序間通訊的機制——訊號量。注意請不要把它與之前所說的訊號混淆起來,訊號與訊號量是不同的兩種事物。有關訊號的更多內容,可以閱讀我的另一篇文章:L

linux程序通訊-訊號

訊號量:是一個計數器,用於為多個程序提供對共享資源的訪問。訊號量是用來調協程序對共享資源的訪問的。為了防止出現因多個程式同時訪問一個共享資源而引發的一系列問題,通過生成並使用令牌來授權,在任一時刻只能有一個執行執行緒訪問程式碼的臨界區域。臨界區域是指執行資料更新

Linux 學習筆記—程序通訊 訊號

2.4訊號 2.4.1 訊號的概念和機制 訊號是UNIX/Linux系統響應某些條件而產生的一個事件,接收到該訊號的程序會相應地採取一些行動。通常訊號是由一個錯誤產生的。但它們還可以作為程序間通訊或修改行為的一種方式,明確地由一個程序傳送給另一個程序。一個訊

linux 程序通訊 訊號

一.訊號量概述 訊號量的使用主要是用來保護共享資源,協調同步使用資源,使得資源在一個時刻只有一個程序(執行緒)所擁有。 二.訊號量的分類 Linux提供兩種訊號量: (1) 核心訊號量,由核心控制路徑使用 (2) 使用者態程序使用的訊號量,這種訊號量又分為POSIX訊號量和SYSTEM V訊號量。

Linux程序同步POSIX訊號

POSIX訊號量是屬於POSIX標準系統介面定義的實時擴充套件部分。在SUS(Single UNIX Specification)單一規範中,定義的XSI IPC中也同樣定義了人們通常稱為System V訊號量的系統介面。訊號量作為程序間同步的工具是很常用的一種同步IPC型別。 在《UNIX網路程式設計 卷

Linux-程序通訊-管道/訊號

pipe     無名管道,只能用於親緣關係的程序間通訊,半雙工,固定讀fd[0],寫fd[1],檔案I/O實現;     當管道中午資料時,讀阻塞;     當寫緩衝區滿時又不被讀走,此時寫阻塞;    

Linux程序通訊-訊號通訊

訊號(signal)機制是unix系統中最為古老的程序間通訊機制,很多條件可以產生一個訊號: 1、當用戶按某些按鍵時,產生訊號 2、硬體異常產生訊號:除數為0、無效的儲存訪問等等。這些情況通常由硬體檢測到,將其通知核心,然後核心產生適當的訊號通知程序,例如:核心對正訪問一個無效儲存區的程