目前我有一個客戶端進程和一個服務器進程。客戶端進程需要每隔一段時間聯繫服務器進程以交換數據,但需要知道服務器的pid才能這樣做。客戶應該如何知道如何做到這一點?我想避免重複的硬盤訪問。此應用程序僅在Linux下運行。目前,服務器通過其存在的pid或RAM磁盤來設置鎖定文件。客戶端檢查文件。我還能如何有效地完成此事務,以便服務器可以向客戶端發送信號? (注:客戶端是PHP,服務器C)簡單的Linux IPC問題
回答
一些想法:
- 什麼都不做;如果您反覆閱讀它,則讀取光盤文件(在適當的永久光盤上)不會導致任何IO,因爲該文件已經在緩存中。
- 重構你的系統,所以你不需要知道pid文件
- 你確定你真的在乎嗎?過早優化和所有這一切。你每秒鐘做多少次,1000次或更多?
一些其他的選項包括:
- 設置服務器偵聽特定端口上。
- 服務器可以設置一個命名管道,客戶端可以通過它進行通信。
所以......沒有人回答我的問題。我的問題不完全是關於IPC。它關於IPC的同步。我已經通過命名管道與客戶端和服務器進行通信。問題是服務器應該如何知道何時收聽管道。現在,這是通過信號完成的(因此知道服務器的pid並將其保留在重複訪問信息不會垃圾郵件讀取的地方)。你是說,而不是試圖同步服務器應該只是聽管道上的客戶端通信,只要它沒有做別的事情? – conartist6 2010-12-23 02:06:55
- UNIX域套接字
- D-Bus
我認爲,當你說 「過程」,這兩個是同一臺機器上?如果是這樣,您可以在/tmp
目錄中使用指定的FIFO。這是使用IPC與指定FIFO /tmp/test.fifo
與fork()
兩個過程的一個例子:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/stat.h>
int errno;
int main(int argc, char** argv)
{
char fifo_path[] = "/tmp/test.fifo";
char buffer[128];
int result = mkfifo(fifo_path, 0600);
printf("mkfifo result = %d\n", result);
if (errno == EEXIST)
printf("errno == EEXIST\n");
pid_t child = fork();
if (child == 0)
{
printf("%d> child; opening fifo \"%s\" for writing\n", getpid(),
fifo_path);
FILE* fifo = fopen(fifo_path, "w");
char in_buffer[128];
fgets(in_buffer, 128, stdin);
fputs(in_buffer, fifo);
fclose(fifo);
}
else
{
printf("%d> parent; opening fifo \"%s\" for reading\n", getpid(),
fifo_path);
FILE* fifo = fopen(fifo_path, "r");
fgets(buffer, 128, fifo);
if (buffer[0] == EOF)
printf("%d> got EOF\n", getpid());
else
{
buffer[strlen(buffer) - 1] = 0;
printf("%d> read string \"%s\"\n", getpid(), buffer);
}
fclose(fifo);
}
return 0;
}
所以只要這兩個進程知道FIFO的完整路徑,就可以讀取和寫入。
這是我已經有的,但問題是同步。目前我的設置是讓客戶端信號服務器準備好進行事務處理,然後事務發生在服務器的信號處理函數中。它如何知道將信號發送到哪個pid? – conartist6 2010-12-23 02:02:16
你不需要知道PID;你只需要知道客戶端是否正在讀取FIFO。有一種方法可以做到這一點;雖然我不確定。我相信服務器在寫入FIFO之前會阻塞,直到它被打開以供讀取。您可以使用某些參數來創建FIFO,這意味着服務器不會阻塞,但是如果沒有從中讀取,服務器將收到SIGPIPE信號。我希望這有幫助。 – Doddy 2010-12-26 18:08:52
通常情況下,您不使用pid,而是使用某種類型的地址 - IP地址(包括端口),Unix域套接字地址,文件系統中的路徑,或者構建於其上的一些更高級別的IPC系統其中一個(D-Bus,X等)可以與服務器進行通信並進行通信。這個pid唯一有用的是發送一個信號,這可能是一種非常糟糕的通信方式,如果將客戶機和服務器劃分爲不同的權限域,則該信號將不起作用。
我想你可以在non_blocking模式下使用名稱IPC消息隊列。我不知道命名管道是否支持non_blocking模式,但如果它是那麼你也可以使用它。在non_block模式下,您只需註冊隊列描述符來發信號並進入一般等待狀態。如果隊列上有任何活動,你的進程將會醒來。請通過互聯網進行一些搜索,你可以找到許多相同的例子。
爲了給出正確的答案,我應該知道你的服務器進程的設計。
- 1. 簡單的IPC通過Linux消息
- 2. IPC SendMessage問題
- 3. IPC問題 - IPC已經註冊
- 4. 在Linux(IPC)
- 5. Linux IPC選擇?
- 6. 簡單的問題
- 7. 簡單的問題
- 8. 簡單的問題
- 9. 實現一個簡單的linux shell的問題
- 10. 簡單Grep問題
- 11. (簡單)問題TweetSharp
- 12. 簡單fizzbuzz問題
- 13. 簡單$ _GET問題
- 14. MVVM簡單問題
- 15. 簡單C問題
- 16. CSS問題簡單
- 17. Xpath簡單問題
- 18. Prolog簡單問題
- 19. Lisp簡單問題
- 20. 簡單TableView問題
- 21. 簡單RDOC問題
- 22. 簡單Jeditable問題
- 23. Drupal簡單問題
- 24. 簡單CARRAY問題
- 25. AVMutableAudioMix簡單問題
- 26. INotifyPropertyChanged簡單問題
- 27. Ajax簡單問題
- 28. Calloc簡單問題
- 29. 簡單的WordPress的問題
- 30. 簡單的jQuery的問題()
正如其他人所建議的,我正在錯誤地處理這個問題,但是:一個方便的方法來完成我當時想做的事情(優化重複的文件系統訪問)是否存在!它是通常安裝在/ dev/shm上的tmpfs文件系統。它可能不是100%可移植的,但它似乎是相當標準的。 – conartist6 2011-02-07 19:37:24