gpt4 book ai didi

c - setpgid 的竞争条件

转载 作者:太空狗 更新时间:2023-10-29 11:13:38 25 4
gpt4 key购买 nike

在为我的 OS 类编写程序时,我发现了一个有趣的案例,该案例涉及一个似乎涉及 setpgid 的竞争条件。

分别编译下面的每个程序。在执行完./test 3(或任意数字> 2)后,ps jx 会显示所有的infy 进程都被放置在同一组。 ./test 2 将出现一个错误,即 setpgid 尝试移动最后一个进程失败。取消注释“修复我”行将导致 ./test 2 按预期工作。

谁能提供解释或解决方案?

// test.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

char* args[] = {
"./infy",
NULL
};

int main(int argc, char* argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s [num]\n", argv[0]);
return 1;
}
int num = strtol(argv[1], NULL, 10);
if (num < 2)
{
fprintf(stderr, "Invalid number of processes\n");
return 1;
}

pid_t pid = fork();
if (pid > 0)
{
int s;
waitpid(pid, &s, 0);
fprintf(stderr, "Children done\n");
}
else
{
pid_t pgid = -1;
int i;
for (i = 1; i < num; i++)
{
pid_t pid2 = fork();
if (pid2 > 0)
{
if (pgid == -1)
{
pgid = pid2;
}
}
else
{
if (setpgid(0, pgid == -1 ? 0 : pgid) != 0)
{
perror("setpgid failed in non-last process");
}
execve(args[0], args, NULL);
perror("exec failed");
exit(1);
}
}

// uncomment me to fix
//fprintf(stderr, "pgid %d\n", pgid);
if (setpgid(0, pgid) != 0)
{
perror("setpgid failed in last process");
}
execve(args[0], args, NULL);
perror("exec failed");
exit(1);
}
}

其中“infy”是一个单独的程序:

// infy.c
#include <unistd.h>

int main()
{
while (1)
{
sleep(1);
}
}

最佳答案

我终于明白了。当 setpgid 失败时,errno 被设置为 EPERMEPERM 的手册页上可能出现的错误之一是:

The value of the pgid argument is valid but does not match the process ID of the process indicated by the pid argument and there is no process with a process group ID that matches the value of the pgid argument in the same session as the calling process.

这种情况下的竞争条件是子进程是否可以在父进程之前设置它的 pgid。如果 child 赢得比赛,一切都很好。如果父进程赢得了比赛,它试图设置的进程组尚不存在,setpgid 失败。

解决方案是让父进程在第一个 fork 之后立即设置子进程的组 ID,方法是在 if (pgid == -1) 中调用 setpgid(pid2, pid2) block 。

也相关,来自手册页:

To provide tighter security, setpgid() only allows the calling process to join a process group already in use inside its session or create a new process group whose process group ID was equal to its process ID.

关于c - setpgid 的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28732764/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com