如何为每个子进程分配一个新的终端窗口

时间:2016-04-11 15:13:47

标签: c linux fork exec ipc

我想分叉多个进程并为每个子进程分配它自己的终端窗口,以便可以轻松演示IPC。 分叉很顺利,如果我在同一个终端上运行子进程,它运行正常。 但是为了使每个子进程都有自己的终端窗口,我做

execl("/usr/bin/xterm", "xterm", "-e", "yourprogram", NULL);

程序在一个新窗口中运行,但其PID不同于父进程显示的PID。我做错了什么?

由于

edit1 - 这是我的主要功能(父进程)。我分叉了4个子进程。我希望每个子进程都有自己的终端窗口。然而,子进程刚退出,并且具有不同PID的新进程继续在新终端中运行。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{

pid_t pid[4]; 
int i = 0;
int status;

//Fork four new processes
for(i=0; i<4; i++)
{
    pid[i] = fork();

    if(pid[i] == 0 && i == 0)
    {
        execl("/usr/bin/xterm", "xterm", "./child1", NULL);
        exit(1);
    }
    else if(pid[i] == 0 && i == 1)
    {
        execl("/usr/bin/xterm", "xterm", "./child2", NULL);
        exit(1);
    }
    else if(pid[i] == 0 && i == 2)
    {
        execl("/usr/bin/xterm", "xterm", "./child3", NULL);
        exit(1);
    }
    else if(pid[i] == 0 && i == 3)
    {
        execl("/usr/bin/xterm", "xterm", "./child4", NULL);
        exit(1);
    }
    else
    {
        //Parent process
        printf("The main function has forked a process with pid: %d\n", pid[i]);
    }
}

for(i=0;i<4;i++)
{
    status = waitpid(pid[i], NULL, 0);
    if(status == pid[i])
        printf("%d: Process Terminated Successfully\n", pid[i]);
    else
    {
        perror("waitpid");
        exit(1);
    }
}

return 1;
}

edit2 - 添加了ps -u输出:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
dell-pc   3024  0.1  0.0  26872  5480 pts/0    Ss   16:54   0:00 bash
dell-pc   3038  0.0  0.0   4200   632 pts/0    S+   16:54   0:00 ./main
dell-pc   3039 22.5  0.1 109240 11116 pts/0    S+   16:54   0:01 xterm ./child1
dell-pc   3040 26.1  0.1 109240 11268 pts/0    R+   16:54   0:02 xterm ./child2
dell-pc   3041 28.7  0.1 109240 11180 pts/0    S+   16:54   0:02 xterm ./child3
dell-pc   3042 27.0  0.1 109240 11288 pts/0    S+   16:54   0:02 xterm ./child4
dell-pc   3044  4.1  0.0   4200   648 pts/24   Ss+  16:55   0:00 child3
dell-pc   3046  3.7  0.0   4200   680 pts/26   Ss+  16:55   0:00 child4
dell-pc   3048  3.8  0.0   4200   792 pts/25   Ss+  16:55   0:00 child2
dell-pc   3050  3.3  0.0   4200   660 pts/14   Ss+  16:55   0:00 child1
dell-pc   3060  2.0  0.0  26816  5412 pts/27   Ss   16:55   0:00 bash
dell-pc   3072  0.0  0.0  22648  2688 pts/27   R+   16:55   0:00 ps -u

edit3:添加了main的输出:

The main function has forked a process with pid: 3491
The main function has forked a process with pid: 3492
The main function has forked a process with pid: 3493
The main function has forked a process with pid: 3494
3491: Process Terminated Successfully
3492: Process Terminated Successfully
3493: Process Terminated Successfully
3494: Process Terminated Successfully

3 个答案:

答案 0 :(得分:1)

我做了一个类似你的程序(命名为stackoverflow),在xterm中执行vi,当它运行时我打开第三个xterm来运行ps -u。输出是:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
osboxes   1713  0.0  0.2   6588  4756 pts/0    Ss   18:56   0:00 bash
osboxes   1780  0.0  0.2   6508  4484 pts/1    Ss   19:12   0:00 bash
osboxes   1836 88.4  0.0   2020   532 pts/0    R+   19:21   0:29 ./stackoverflow
osboxes   1837  0.1  0.4  12844  8952 pts/0    S+   19:21   0:00 /usr/bin/xterm -e vi stackoverflow.txt
osboxes   1839  0.0  0.1   6072  3536 pts/2    Ss+  19:21   0:00 vi stackoverflow.txt
osboxes   1840  0.0  0.1   4772  2452 pts/1    R+   19:22   0:00 ps -u

计划的输出是:

PID=1836
child PID=1837

因此,孩子仍在运行xterm命令。它创建了另一个运行vi(pid 1839)的孩子。

答案 1 :(得分:1)

使用终端窗口在下的IPC演示和示例

因为在下很容易:

这将需要简单的终端工具,例如xterm。已使用lxtermmate-terminalkonsolegnome-terminal成功地对此进行了测试。当然,tmuxscreen也必须能够...

好吧,我们走吧。我们假设您已经在某个终端窗口中,我们将其命名为初始控制台

1。首先打开显示窗口:

因此,从初始控制台中,打开日志窗口

exec 5> >(xterm -T 'Log window...' -e sh -c "cat /proc/$$/fd/5")

exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';cat /proc/$$/fd/5")

exec 5> >(konsole --nofork -e sh -c "cat /proc/$$/fd/5")
exec 5> >(lxterm -T "Log window..." -e sh -c "cat /proc/$$/fd/5")
exec 5> >(mate-terminal -t 'Log window...' -x sh -c "cat /proc/$$/fd/5")
exec 5> >(gnome-terminal --window -x sh -c "printf '\\e];Log window...\\a';cat /proc/$$/fd/5")

Variant可用于调试

exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';
              tee </proc/$$/fd/5 /dev/tty | sed -u s/.*/now/|date -f -")

将在每行输出上打印日期和时间。

exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';
              tee </proc/$$/fd/5 /dev/tty | sed -u s/.*/now/|date -f - ; read foo")

相同,但是从父级关闭后将保持窗口打开,在关闭(或由窗口管理器关闭)之前等待终端输入( Return )。

2。测试,然后使用:

始终在初始控制台中,点击:

echo >&5 This is a test string.

这必须在“日志”窗口中提示。

好,现在:

xterm -T 'Input window' -e bash --rcfile <(echo "exec 1>/proc/$$/fd/5") &

注意:在此处, 双引号 将确保$$初始窗口扩展的外壳层。

现在,您可以在输入窗口中输入命令,并在日志窗口中读取结果。

3。关闭窗口

关闭文件描述符时窗口将关闭:

exec 5>&-

使用3个窗口的完整脚本

您可能会在其中找到完整的脚本:

答案 2 :(得分:0)

对于我使用的gnome终端:

execl("/usr/bin/gnome-terminal", "gnome-terminal", "-q", "-e", "./my_binary", (char*)0);