2013-04-18 125 views
4

我已經編寫了客戶端服務器代碼,我有很多連接,假設每個節點代表不同的進程在同一臺機器上。要做到這一點,我顯然使用fork()。如何通過linux中的C程序打開新終端

但現在的問題是,所有的結果都顯示在同一個終端上。 我想知道是否有任何方式,例如在每個fork()或進程創建後,新的終端打開,並在特定終端上顯示該進程的所有結果。

P.S:我試過system("gnome-terminal"),但它只是打開新的終端,但所有的結果只能在同一個終端上顯示。所有新的終端只是開放,並保持空白,沒有任何結果。

另外我已經通過這個鏈接How to invoke another terminal for output programmatically in C in Linux但我不想運行我的程序參數或任何。它應該就像./test

這裏是我的代碼: -

for(int i=0;i<node-1;i++) 
    { 
    n_number++; 
    usleep(5000); 
    child_pid[i]=fork(); 
    if(!child_pid[i]) 
    { 
     system("gnome-terminal"); 
     file_scan(); 
     connection();   
     exit(0); 
    }  
    if(child_pid[i]<0) 
     printf("Error Process %d cannot be created",i); 
    } 
    for(int i=0;i<node-1;i++) 
    wait(&status); 

所以基本上我想要的是每個過程應該只顯示過程信息或結果的新終端。

我到底要:

  • 叉()之後,我不得不說的過程1,那麼我想它輸出到一個終端
  • 也是一樣與每個進程相關的一些數據。因此,如果我有3個過程,那麼必須有3個終端,每個終端只能顯示與過程相關的數據。

我知道它可以使用IPC(Inter Process Communication)來實現,但是有沒有其他解決方法?我的意思是隻有2-3個左右的命令?因爲我不想在這部分編碼上投入太多。

在此先感謝!

+0

原始流程將如何安排寫入終端?新終端中的哪個進程會顯示您編寫的信息? –

+0

@JonathanLeffler我希望我能記住更多的文件描述符和流,但理論上你不能打開一個新的終端並將'stdout'重定向到該終端的任何文件描述符?嗯,我想我是誤解終端... – rliu

+1

我的懷疑/期望是,在沒有其他任何東西的情況下,終端設置有自己的外殼,並有自己的(驚喜)終端('/ dev/ttyXXX'或'的/ dev/ptyXXX')。因此,可能需要一些謹慎的管道操作,以便終端窗口的輸入來自想要寫入它的進程,並且需要一個程序(也許是'cat'?)來讀取該輸入並寫入終端窗口。我沒有做到,所以我不知道這些技巧是什麼。 (你有沒有試過'man gnome-terminal'?) –

回答

5

也許你想要那樣的東西。該程序使用unix98僞終端(PTS),它是主從機之間的雙向通道。因此,對於您所做的每個分支,您都需要創建一個新的PTS,通過調用三元組posix_openpt,grantpt,主控端解鎖以及從屬端的ptsname。不要忘記糾正每邊的初始文件描述符(stdin,stdout和sdterr)。

請注意,這只是一個程序來證明這個概念,所以我沒有做任何形式的錯誤檢查。

#define _XOPEN_SOURCE 600 
#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <libgen.h> 
#include <string.h> 
#include <fcntl.h> 

int main() { 
    pid_t i; 
    char buf[10]; 
    int fds, fdm, status; 

    fdm = posix_openpt(O_RDWR); 
    grantpt(fdm); 
    unlockpt(fdm); 

    close(0); 
    close(1); 
    close(2); 

    i = fork(); 
    if (i == 0) { // father 
    dup(fdm); 
    dup(fdm); 
    dup(fdm); 
    printf("Where do I pop up?\n"); 
    sleep(2); 
    printf("Where do I pop up - 2?\n"); 
    waitpid(i, &status, 0); 
    } else { // child 
    fds = open(ptsname(fdm), O_RDWR); 
    dup(fds); 
    dup(fds); 
    dup(fds); 
    strcpy(buf, ptsname(fdm)); 
    sprintf(buf, "xterm -S%c/2", basename(buf)); 
    system(buf); 
    exit(0); 
    } 
} 
+0

'sprintf(buf,「xterm -S%c/2」,basename(buf));'應該是'char *'的%s。 –