2012-05-28 29 views
4

我正在爲我的CS類編寫一個shell,並且如果用戶傳入了'&'字符,部分項目涉及在後臺運行進程。發送進程到後臺並將控制返回到我的shell

如果一個進程在前臺運行,我只需要execvp該進程,並且它仍處於終端的控制之中,因爲它在前臺。但是,如果它是後臺進程,那麼在開始執行進程後,我必須將控制權返回到主外殼程序。我知道系統調用tcsetpgrp(pid_t)將進程作爲參數放在前臺,但我不太明白如何使用它。

如果是後臺進程,我應該在execvp之後調用tcsetpgrp嗎?如果是這樣,我可以通過調用getpid來獲得我的shell的pid嗎?

+0

讓我們試試這個。在你最喜歡的終端發起兩場會議。在第一個運行一個命令,讓說**貓**,這是在fg。切換到其他會話,使用ps **找到cat的** pid。發送信號** SIGSTOP **使用** kill **。觀察發生的情況並分享您的發現。 – tuxuday

回答

-1

您應該看看fork來創建子進程。然後,在子中使用exec運行所需的命令。

8

tcsetpgrp()適用於進程組,而不是個別進程。你想要做的是這樣的:

  1. 當你創建一個新的管道,稱之爲setpgid()把管道中的所有成員在新的進程組(第一進程的PID在管道作爲PGID)。 (流水線是你的shell在看到像ls | grep foo | wc -l這樣的請求時啓動的一系列進程 - 最簡單的流水線只有一個進程)。通常情況下,您會在撥打exec()之前從管道中的第一個過程中撥打setpgid(0, 0)

  2. 使用tcsetpgrp()來管理哪個進程組位於前臺。如果將進程組從前臺移動到後臺,您可以將該進程組的自己的進程組設置爲前臺進程組 - 您可以在shell中使用getpgid(0)

  3. 當shell在後臺時,它應該使用阻塞waitpid()調用來等待子進程退出而不是顯示提示。一旦前臺管道中的每個進程退出,它都應該將自己重新放回前臺(並顯示提示)。

  4. 當shell是在前臺,它應該調用waitpid()WNOHANGWUNTRACED標誌來檢查子進程的狀態顯示您提示之前 - 這會告訴你,當他們停止或退出,並讓你通知用戶。

+0

謝謝caf,非常有幫助 – user1420913

-1

如果你的外殼開始使用&背景是一個過程,$! shell變量將包含子進程的PID。然後您可以發送信號到該過程,或使用wait $!等待它完成。