2010-06-08 88 views
2

喂一次親愛的互聯網之間,C:先進先出線程,寫入和讀取字符串

我寫一個小程序,除其他事項外,寫入日誌文件中的所有收到的命令。
爲此,我想使用一個只會嘗試從管道中讀取的線程,而主線程只要它應該寫入該管道。

由於我不知道每個字符串命令的長度,所以我想到了寫入和讀取指向char buf[MAX_MESSAGE_LEN]的指針。
因爲我到目前爲止已經試過不行,我會後我最大的努力:P

char str[] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n"; 
    if (pipe(pipe_fd) != 0) 
     return -1; 
    pthread_t log_thread; 
    pthread_create(&log_thread,NULL, log_thread_start, argv[2]); 
    success_write = 0; 
    do { 
     write(pipe_fd[1],(void*)&str,sizeof(char*)); 
    } while (success_write < sizeof(char*)); 

和線程做這樣的:

char buffer[MAX_MSGLEN]; 
    int success_read; 
    success_read = 0; 
    //while(1) { 
     do { 
      success_read += read(pipe_fd[0],(void*)&buffer, sizeof(char*)); 
     } while (success_read < sizeof(char*)); 
    //} 
    printf("%s",buffer); 

(很抱歉,如果這並未」噸縮進,我似乎無法弄清楚這個編輯器......) 哦,而pipe_fd[2]是一個全局參數。

因此,無論是按照我的想法,還是以另一種方式閱讀字符串而不知道長度,我都非常感謝。

在附註上,我正在研究Eclipse IDE C/C++,版本1.2.1,我似乎無法設置編譯器,因此它會將pthread庫鏈接到我的項目。我使用自己的Makefile來製作它(雙關語:P)。任何人都知道如何解決鏈接問題?我在網上看過,但我找到的所有解決方案都適用於舊版本,因爲選項卡和選項鍵不同。

反正,感謝一堆互聯網! Yonatan

+0

修正了您的縮進問題,使用代碼按鈕的同時突出顯示較大的代碼塊。 ''語法是用於內聯代碼的。 – Femaref 2010-06-08 11:23:53

回答

0

你爲什麼要讀寫數據的是大小爲sizeof(char*)的字節,即4或8字節?您不會被強制讀取和寫入相同數量的字節!

如果您的問題是您沒有在讀取線程中收到數據,則應該在寫入後使用sync()考慮同步。

+0

不,fflush()用於刷新stdio緩衝區。他直接使用read()和write(),它繞過了stdio。 – psmears 2010-06-08 11:57:05

0

對我來說,如果你碰巧讀或寫了太多內容,那麼你的代碼就會終止。你應該有,而成功讀取< MAX_MSGLEN或sizeof(str)。

0

你真的需要額外的線程嗎?正如你發現的那樣,添加線程會增加很多複雜性......在這種情況下,寫入管道的速度不會比寫入文件的速度快得多 - 事實上,它最終可能會在實踐中變慢,因爲write()沒有fprintf()和朋友所做的緩衝。最好的解決方案可能是直接寫入日誌文件...

0

你試過socketpair(AF_UNIX,SOCK_DGRAM)嗎?它的性質是可靠的,並且會爲你劃定信息。

就你而言,你必須確保MAX_MESSAGE_LEN小於PIPE_BUF,這是平臺對pipe()的內部緩衝區的限制。

顯然,將指針的發送/記錄改變爲發送實際的字符串,例如,:

- char str[] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n"; 
+ char str[MAX_MESSAGE_LEN] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n"; 

- write(pipe_fd[1],(void*)&str,sizeof(char*)); 
+ write(pipe_fd[1],(void*)&str,MAX_MESSAGE_LEN); 
0

您沒有更新循環中的success_write

0

因此,任何幫助,無論是我想到的方式,或另一種方式,我可以閱讀字符串不知道長度,將不勝感激。

您可以創建一個簡單的協議來通過FIFO /管道進行通信。寫入器線程將一個字節寫入FIFO以指示消息長度,然後寫入可變長度消息。讀取器將讀取一個字節以瞭解消息的長度,然後針對指定的消息長度發出後續讀取命令。

你可能想看看這個answer到FIFO的類似question更多的細節。