0

我正在编写一个功能非常类似于聊天室的 TCP 服务器并遇到了这个问题。

当用户连接时,会创建一个子进程来为用户服务。
当用户登录时,我将他的用户名存储到一个文本文件中,online.txt
但是当用户注销时,我需要从(问题)中删除用户,然后是online.txt父级并杀死孩子。signalsreaper()

我的问题是:

Q1:我如何向收割者提供额外的信息(例如用户用于登录的用户名),以便它也可以将用户从中删除online.txt?或者还有其他更好的方法吗?

Q2:siginreaper()的价值从何而来?我可以向收割者添加其他参数吗?

Q3:我可以使用孩子的 pid 作为 login.txt 的某种主键吗?如果是这样,我如何reaper()在父母调用的过程中检索孩子的 pid?

收割者看起来像这样:

void    reaper(int sig)//where does sig come from?
{
int status;

while (waitpid(-1, &status, WNOHANG) >= 0)
    ;
}

父级使用的信号如下所示:

(void) signal(SIGCHLD, reaper);//how can I add more parameters?

提前谢谢你,我希望一次问3个问题不会太贪心。
对任何问题的任何见解都将不胜感激。

4

2 回答 2

2

据我从您的问题中收集到的,父进程将 reaper() 注册为 SIGCHLD 的处理程序。当它检测到登录时,它将用户名写入文件,并产生一个孩子。

注销时会调用 reaper() 函数,因为子进程检测到注销并因此退出,对吗?

如果是这样,为什么不让服务器维护一个将 PID 映射到用户名的数据结构。然后从 waitpid 中获取返回值并确定需要从文件中删除哪个用户名。

所以,总结一下:

1) 不,是的。

2)来自处理程序接收到的信号。不。

3) 是的。从 waitpid() 的返回值。

于 2010-12-09T15:29:56.340 回答
1

问题 1:为您的子进程配置信号处理程序以执行某些特定操作是否合适?然而,也许更好的解决方案是不使用文件,而是使用内存结构来存储用户登录的内容。这样,收割者可以从内存中删除条目,甚至删除建议的信号处理程序。

问题 2:我不熟悉您的操作系统或架构,但我猜想 SIGCHLD 将被传递给 reaper( int sig ) 作为参数值。

问题 3:获取 pid 是特定于操作系统的。对于 POSIX 类型,它通常是来自 unistd 的 getpid()。但是我会质疑您是否真的想对文件执行此操作。

当您开始在各处发出信号时,您的解决方案可能会受到竞争条件的影响……这会带来安全风险。

各位网友,欢迎指正。在寻求智慧的过程中,必须接受指导。

于 2010-12-09T15:36:47.993 回答