[Android]進程間通信的方法


一、管道

管道是進程間通信中最古老的方式,它包括 無名管道 和 有名管道兩種,前者用於父進程和子進程間的通信,后者用於運行於同一台機器上的任意兩個進程間的通信。 無名管道由pipe()函數創建。

#include <stdio.h> 
#include <unistd.h>
 
#define INPUT 0
#define OUTPUT 1
 
int main()
{
    int files[2];
    pid_t pid;
    char buf[256];
    int returned_count;
    
    //創建無名管道
    pipe(files);
 
    //創建子進程
    
    if((pid = fork()) == -1) 
    { 
        perror("fork() error");
        return -1; 
    } 
 
    //執行子進程
    if(pid == 0)
    { 
        printf("in child process....\n");
 
        //子進程向父進程寫數據,關閉管道的讀端
        close(files[INPUT]);
        write(files[OUTPUT],"test data", strlen("test data"));
     
        exit(0);
    } 
    else
    { 
        //執行父進程
        printf("in the parent process...\n");
        //父進程從管道中讀取子進程寫的數據,關閉管道的寫端
        close(files[OUTPUT]);
 
        returned_count = read(files[0], buf, sizeof(buf));
        buf[returned_count] = '\0';
        printf("%d bytes of data receiced from spawned process:%s\n", returned_count, buf);
    } 
    
    return 0;
}

二、消息隊列

消息隊列用於運行於同一台機器上的進程間通信,它和管道很相似,是一個在系統內核中用來保存消息的隊列,它在系統內核中是以消息鏈表的形式出現。消息鏈表中節點的結構用msg聲明。

事實上,它是一種正逐步被淘汰的通信方式,我們可以用流管道或者套接口的方式來取代它。所以,我們對此方法也不再解釋,也建議讀者忽略這種方式。

三、共享內存

共享內存是運行在同一台機器上的進程間通信最快的方式,因為數據不需要在不同的進程間復制。通常由一個進程創建一塊共享內存區,其余進程對這塊內存區進行讀寫。得到共享內存有兩種方式:映射/dev/mem設備和內存映像文件。前一種方式不給系統帶來額外的開銷,但在現實中並不常用,因為它控制存取的將是實際的物理內存,在Linux系統下,這只有通過限制Linux系統存取的內存才可以做到,這當然不太實際。常用的方式是通過shmXXX函數族來實現利 用共享內存進行存儲的。 使用共享內存時要掌握的唯一訣竅是多個進程之間對一定存儲區d同步訪問。若服務器進程正在將數據放入共享內存,則在它做完這一操作之前,客戶進程不應當去讀取這些數據。 通常,信號量是用來實現對共享內存訪問的同步(記錄鎖也可以用於這種場合)。 使用共享存儲來實現進程間通信的注意點是對數據存取的同步,必須確保當一個進程去讀取數據時,它所想要的數據已經寫好了。通常,信號量被要來實現對共享存 儲數據存取的同步,另外,可以通過使用shmctl函數設置共享存儲內存的某些標志位如SHM_LOCK、SHM_UNLOCK等來實現。

四、信號

信號是比較復雜的通信方式,用於通知接受進程有某種事件發生,除了用於進程間通信外,進程還可以發送信號給進程本身;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標准的信號函數sigaction(實際上,該函數是基於BSD的,BSD為了實現可靠信號機制,又能夠統一對外接口,用sigaction函數重新實現了signal函數)。

五、信號量

信號量又稱為信號燈,它是用來協調不同進程間的數據對象的,而最主要的應用是前一節的共享內存方式的進程間通信。本質上,信號量是一個計數器,它用來記錄對某個資源(如共享內存)的存取狀況。一般說來,為了獲得共享資源,進程需要執行下列操作:   
(1) 測試控制該資源的信號量。   
(2) 若此信號量的值為正,則允許進行使用該資源。進程將信號量減1。   
(3)若此信號量為0,則該資源目前不可用,進程進入睡眠狀態,直至信號量值大於0,進程被喚醒,轉入步驟(1)。   
(4)當進程不再使用一個信號量控制的資源時,信號量值加1。如果此時有進程正在睡眠等待此信號量,則喚醒此進程。  

維護信號量狀態的是Linux內核操作系統而不是用戶進程。我們可以從頭文件/usr/src/linux/include/linux/sem.h 中看到內核用來維護信號量狀態的各個結構的定義。信號量是一個數據集合,用戶可以單獨使用這一集合的每個元素。要調用的第一個函數是semget,用以獲得一個信號量ID。

六、套接口

套接口(socket)編程是實現Linux系統和其他大多數操作系統中進程間通信的主要方式之一。我們熟悉的WWW服務、FTP服務等都是基於套接口編程來實現的。除了異地的計算機進程間外,套接口同樣適用於本地同一台計算機內部的進程間通信。 關於這部分,可以參照《設計自己的網絡螞蟻》。那里由常用的幾個套接口函數的介紹和示例程序。
這一部分或許是Linux進程間通信編程中最須關注和最吸引人的一部分,畢竟,Internet 正在我們身邊以不可思議的速度發展着,如果一個程序員在設計編寫他下一個程序的時候,根本沒有考慮到網絡,考慮到Internet,那么,可以說,他的設計很難成功。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM