我想分叉多个进程并为每个子进程分配它自己的终端窗口,以便可以轻松演示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
答案 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)
因为在bash下很容易:
这将需要简单的终端工具,例如xterm
。已使用lxterm
,mate-terminal
,konsole
和gnome-terminal
成功地对此进行了测试。当然,tmux
和screen
也必须能够...
好吧,我们走吧。我们假设您已经在某个终端窗口中,我们将其命名为初始控制台。
因此,从初始控制台中,打开日志窗口:
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")
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 )。
始终在初始控制台中,点击:
echo >&5 This is a test string.
这必须在“日志”窗口中提示。
好,现在:
xterm -T 'Input window' -e bash --rcfile <(echo "exec 1>/proc/$$/fd/5") &
注意:在此处, 双引号 将确保$$
从初始窗口扩展的外壳层。
现在,您可以在输入窗口中输入命令,并在日志窗口中读取结果。
关闭文件描述符时窗口将关闭:
exec 5>&-
您可能会在其中找到完整的脚本:
答案 2 :(得分:0)
对于我使用的gnome终端:
execl("/usr/bin/gnome-terminal", "gnome-terminal", "-q", "-e", "./my_binary", (char*)0);