2012-05-21 156 views
11

不止一個獨立的程序之間相同的變量,我想分享在Linux中不止一個無關的C可執行文件之間的變量。也就是說,一個程序將寫入一個數組並設置一個標記,以便其他程序不能使用它,在此操作之後,它將取消設置該標記,然後另一個程序將讀取該數組。我嘗試在每個程序中使用相同的自定義頭文件(包含變量),但似乎在調用程序時創建了不同的變量實例。共享在Linux中

+8

提示:IPC(進程間通信),在這裏回答這個問題太大了。 – Nim

+2

是的,你可能想看看[這裏](http://en.wikipedia.org/wiki/Inter-process_communication)。兩個獨立的可執行文件將在不同的進程中啓動,因此您必須使用[套接字](http://www.cs.cf.ac.uk/Dave/C/node28.html)實現它們之間的某種通信。 ,[管道](http://www.cs.cf.ac.uk/Dave/C/node23.html)等...甚至文件。 –

+0

我明白了。這意味着,在這種情況下必須使用管道。有沒有更簡單的方法? –

回答

14

你在頭文件中聲明的變量將產生一個副本你在哪裏都包括他們(unless you declare them extern)。當然,在處理單獨的進程時,每個進程都有自己的內存空間。您需要使用更復雜的技術來規避此問題,即進程間通信(IPC)。例如:

  • (命名)管道
  • 套接字
  • 共享內存

你的問題讀起來就像shared memory是你想要的,因爲由此多個進程可以訪問同一存儲區域分享一些變量。也許看看this question及其答案爲例。

將需要你的程序來創建某些共享存儲器,例如使用shmget並使用shmat附加共享內存對象。 當多個進程訪問相同的內存區域時,在讀取/寫入變量期間添加進程同步始終是一種健康的方法,例如,使用共享信號量(semgetsemop)。

當你與你共享內存中完成,你需要從中分離(shmdt)。因此你告訴內核你的進程不再需要訪問它。 創建共享存儲器/信號量對象的方法,也需要在程序(一個或多個)的端部以破壞它們。否則,將駐留在內存中,或許直到你重新啓動機器(見shmctlsemctl,尤其是IPC_RMID)。

請注意,對於共享內存對象「在最後一個進程分離它之後,該段實際上只會被銷燬」。所以你想確保,這確實發生在你的所有流程中(shmdt)。


響應於該評論,這裏是POSIX的方法:

System V共享存儲器(shmget的(2),shmop(2)等)是較舊的共享存儲器的API。 POSIX共享內存提供了一個更簡單,設計更好的界面;另一方面,POSIX共享內存與System V共享內存相比可用性稍差(特別是在較早的系統上)。

後也見例子this overviewhere

最後,注意

POSIX共享內存對象有內核的持久性:共享內存對象會一直存在,直到系統被關閉,或者直到所有進程都映射的對象,它已經與shm_unlink刪除(3)


爲了考慮到共享內存中對象的持久性,不要忘了信號處理程序添加到您的應用程序,將在出現異常的情況下,執行清理行動終止(SIGINT,SIGTERM等)。

+3

不要使用'shmget',而是使用posm'shm_open'。這是不太痛苦的使用,並沒有關鍵衝突的問題 – Hasturkun

+0

@Hasturkun - 感謝您的評論!到目前爲止,我還沒有使用過這些內容,但爲了完整性,我添加了一個註釋。 – moooeeeep

+0

謝謝moooeeeep。 –

6

查找到通過shm_openshm_unlink使用POSIX共享內存...我個人覺得他們是更容易使用和更直接的比舊的系統V IPC調用如shmget等由於把手正好返回作品就像一個文件描述符一樣,你可以使用readwrite等調用。否則,如果你想通過普通指針訪問文件描述符所表示的共享內存對象,你可以在shm_open返回的文件描述符上使用mmap