我的应用程序的一个线程负责以bash命令的形式运行多个进程。它在一个循环中运行,并为每个找到的文件运行指定的命令。
foreach (var file in files)
{
string withoutExt = Path.GetFileNameWithoutExtension(file);
string outputFile = Path.GetDirectoryName(file) + "/" + withoutExt + ".png";
tasks.Add(Task.Run(delegate
{
ProcessStartInfo startInfo = new ProcessStartInfo()
{ FileName = "neato", Arguments = $"-Tpng {file} -o {outputFile}", };
Process.Start(startInfo)?.WaitForExit();
}));
}
Task.WaitAll(tasks.ToArray());虽然它完成了它的工作,但我注意到,当我的应用程序被强制关闭或崩溃时,这些进程都是活动的。当我在太多的文件上运行这段代码时,我发现了这一点:数以百计的进程吞噬了我所有的资源,当我终于关闭了一个应用程序时,它们仍然持续存在。
我正在寻找一种方法,以某种方式将这些进程绑定到主线程,所以当我关闭主线程时,它们都会被清除。
我知道在StackOverflow上已经有人问过这样的问题,但据我所见,这里提出的解决方案严格地绑定到Windows,而不是Linux。
发布于 2022-02-13 18:40:37
确保一组创建的进程能够可靠地被杀死的一种方法是在一个新的中启动它们。
在这样的名称空间中,“根”进程具有pid 1 (init)。一旦该根进程被杀死,Linux内核将确保名称空间中的所有其他进程都被杀死。这将独立于与这些进程相关联的会话或流程组。
在我需要可靠地终止从Python开始的shell进程的情况下,这对我来说很好。通过unshare shell命令在新的pid命名空间中启动子进程很容易。
发布于 2022-02-15 05:31:46
或者用一个尝试接住的方法来处理坠机?
{
List<string> pID = new List<string>();
try
{
foreach (var file in files)
{
string withoutExt = Path.GetFileNameWithoutExtension(file);
string outputFile = Path.GetDirectoryName(file) + "/" + withoutExt + ".png";
tasks.Add(Task.Run(delegate
{
ProcessStartInfo startInfo = new ProcessStartInfo()
{ FileName = "neato", Arguments = $"-Tpng {file} -o {outputFile}", };
string pid = Process.Id.ToString();
pID.Add(pid);
Process.Start(startInfo)?.WaitForExit();
}));
}
Task.WaitAll(tasks.ToArray());
}
catch (Exception e)
{
# kill all the processes
foreach (var pid in pID)
{
try
{
Process.GetProcessById(int.Parse(pid)).Kill();
}
catch (Exception)
{
// ignore
}
}
}
}发布于 2022-02-17 19:54:12
在启动进程之前设置process.EnableRaisingEvents = true;显然,这在Linux中非常重要,因为子进程与父进程一起退出。
https://github.com/dotnet/runtime/issues/21661
如果您正在码头容器中运行,请确保传递--init,以便清理子进程。
https://stackoverflow.com/questions/71018944
复制相似问题