如何将进程分叉到另一个虚拟终端

问题描述 投票:0回答:1

我需要一种方法将当前进程分叉到另一个虚拟终端中。实际上,我想将我的进程的子进程生成到单独的 tmux 窗格中,但是知道如何分叉到另一个控制台就可以了,其余的应该很容易。

unix terminal fork
1个回答
0
投票

将单个进程移至另一个终端

首先让我们看看如何将单个进程抓取到另一个控制台中。在 Linux 中,您可以使用 reptyr 将进程重新附加到另一个终端。这相当容易。

假设这是您的主程序

#!/usr/bin/perl

print "My PID is $$\n"; # print current process PID;
sleep 10;

while(1){
  print ++$i, "\n";
  sleep 1;
}

它会打印自己的PID,然后在一段时间后开始计算秒数。

你应该跑

reptyr [PID-number]

在新终端中(将程序打印的PID放在

[PID-number]
的位置),你会看到我们的主程序将被移动到新终端中。

非常简单

将子进程移至另一个终端

如果您尝试使用新分叉来完成此操作,

reptyr
将失败并出现以下错误:

[-] Process 739989 (test2.pl) shares 739990's process group. Unable to attach.
(This most commonly means that 739990 has sub-processes).
Unable to attach to pid 739990: Invalid argument

当您创建分叉时,它开始与父进程共享一个组(解释进程组内容的文章链接位于本文末尾)。由于某种原因,您

reptyr
无法抢夺属于某个组的进程。要在该子进程上使用
reptyr
,您应该将其取消分组,或者更精确地通过调用
setpgid($$, $$)
将其设置为自己的组,这会将当前进程分配到 ID 为当前进程的进程 ID 的组。这会将孩子移动到自己的组中,
reptyr
将能够“抢夺”它。

#!/usr/bin/perl

use POSIX;

$pid = fork();
if ($pid)
{
  # parent process
  print "Child PID is $pid\n";
  sleep 10;
  while (1) {print ".\n"; sleep 1};
} else
{
  # child process
  (setpgid($$,$$) != -1)           || die "Can't set own group: $!";
  sleep 10;
  while (1) {print ++$i,"\n"; sleep 1};
}

这里父进程打印点,子进程计算秒。它还在开始时打印子 PID。

如果您什么都不做,父级和子级的输出将混合在您运行它的终端中。但如果你跑步

reptyr [child-PID-number]

在新终端中(将程序打印的子PID放在

[child-PID-number]
的位置),您将看到父程序的输出(点)将保留在旧终端中,而子程序的输出(数字)将移动到新航站楼。

另请参阅

为了更好地理解流程组的内容,您应该阅读这篇文章:https://blog.nelhage.com/2011/02/changing-ctty/

© www.soinside.com 2019 - 2024. All rights reserved.