2012-07-19 61 views
4

我正在編寫一個程序,一旦按下按鈕,我必須執行一個服務器進程(只有當我決定殺死他時纔會停止)。
要執行這個過程中,我決定使用fork/execv機制:C++:fork/exec還是pthread?

void Command::RunServer() { 

    pid = fork(); 

    if (pid==0) { 
     chdir("./bin"); 
     char str[10]; 
     sprintf(str,"%d",port); 
     char *argv[] = {"./Server", str}; 
     execv("./Server",argv); 
    } 
    else { 
     config->pid = pid; 
     return; 
    } 
} 

而且在方法「按鈕按下」,我做的:

command->RunServer(); 

它似乎很好的工作了幾天前...現在我得到錯誤:

main: xcb_io.c:221: poll_for_event: Assertion `(((long) (event_sequence) - (long) (dpy->request)) <= 0)' failed. 

我應該嘗試切換到pthread嗎?我做了什麼壞事?

感謝,
EO

+3

說'的char * argv的[] = { 「./Server」,STR,NULL};' – 2012-07-19 08:28:56

+0

不會改變任何東西... – eouti 2012-07-19 08:46:45

+0

哦,是對不起它改變了什麼。 'ps'中的過程描述現在是乾淨的,之前有很多參數非常難看。 – eouti 2012-07-19 09:05:49

回答

5

當你做你的fork()過程的所有文件描述符被複制在新的一個。當你做exec*()所有的文件描述符也被保留,除非它們被標記爲FD_CLOEXEC

我的猜測是某些庫(Xlib,可能)使用的某些fd被新進程繼承,並且該複製導致程序中出現混亂。

如果您想保持標準I/O打開,在這些情況下BSD功能closefrom()closefrom(3))是有用的。不幸的是,在Linux中有沒有這樣的功能,所以你必須做一個近距離的所有循環或類似的克魯夫特:

int open_max = sysconf (_SC_OPEN_MAX); 
for (int i = 3; i < open_max; i++) 
    close(i); 

你可以閱讀更多關於這個問題here

+0

好:)似乎工作..它爲什麼從3開始?前兩個是特定的東西? – eouti 2012-07-19 08:48:45

+0

stdin,stdout,stderr。第一個_three_是特殊的。 – MSalters 2012-07-19 08:53:20

+0

好的。感謝您的解釋。 – eouti 2012-07-19 08:54:10

3

在呼叫execv,argv必須由空指針終止。 前行應該是:

char* argv[] = { "./Server", str, NULL }; 
+0

是的,謝謝我注意到了這一點,當它不是由NULL指針結束時,我的進程名稱非常醜陋與未編碼的字符。它現在運作良好。 – eouti 2012-07-19 09:44:14