gpt4 book ai didi

c - 使用 Pipe()、fork() 和信号处理来管理程序中的内存和管道/套接字

转载 作者:行者123 更新时间:2023-11-30 14:51:05 24 4
gpt4 key购买 nike

使用forkpipesignal.h信号处理。 STDIN 用于快速模拟与网络服务器的套接字连接。伪代码:

struct message_t {
uint32_t length;
uint8_t *data;
};

int is_shutdown = 0;

void signal_handler(int) {
//set is_shutdown if SIGINT
}

int main() {
//initialize
pipe();
fork();

if (parent) {
while(!is_shutdown) {
//0. initialize variables, buffer, message_t
//1. read string of unknown length from STDIN (or socket) to a buffer
//2. malloc() message_t and fill it's fields
//3. write() message_t to pipe
//4. free() message_t
}
}

if (child) {
while(!is_shutdown) {
//0. initialize variables, message_t
//1. read() message_t: read length, malloc() buffer, read data
//2. execute command
//4. free() message_t
}
}

//close pipe
}

有几件事让我困惑:

  1. 我应该在信号处理程序中close()pipe吗?
  2. 我不完全明白发送消息(父级)后消息(它的内存)会发生什么。我应该在 write() 之后free() 缓冲区吗?
  3. 如何处理信号处理程序的资源释放。我是否应该将缓冲区和 fd 实现为全局变量,以便从信号处理程序访问它们
  4. is_shutdown 标志和进程间通信。我的理解是否正确,父级和子级不会将 is_shutdown 共享为同一个变量(它们是副本)并且更改一个不会更改另一个?
  5. 信号处理程序和 main 并发访问 is_shutdown 怎么样?有什么隐藏的细节,比如通过多线程实现并发吗?
  6. 当一个进程关闭时,另一个进程仍然在工作。如果管道发生问题,我将无法通知对方。我应该希望收到 SIGPIPE 吗?
  7. 我怀疑从性能的角度来看,在父级 while 循环的每次迭代中调用 malloc() 并不明智。但是定义“足够大”的缓冲区感觉就像一个黑客(如果有一天它不够大怎么办)。我错了吗?

我对 C 语言及其内存和资源管理还很陌生:从用于强大的基于 Intel 的服务器/桌面的 C++14 开发切换到用于约 180MHz ARM 嵌入式系统的 C 开发,所以我可能会太担心并忘记一些明显的事情事情。

最佳答案

  1. 不,你不应该。在信号处理程序中您应该做的唯一事情是设置is_shutdown
  2. write 进行复制。 write 返回后,可以安全地重用或释放缓冲区。 (不过,请确保处理短写入。)
  3. 你不知道。同样,您在信号处理程序中应该做的唯一事情就是设置is_shutdown。 while 循环终止后清理 parentchild block 。
  4. 是的,每个进程都有一个独立的副本。您还应该知道,通过这种设计,如果您从终端运行该程序,然后在其中键入 ^C,内核将在这两个进程上触发 SIGINT,因为它们都位于同一进程组中。
  5. is_shutdown 需要使用 volatile sig_atomic_t 类型进行声明,并且,对于像这样的简单程序,除了信号处理程序之外,不应该由任何其他程序写入它。此外,信号处理程序不应读取其值,而应仅设置它。根据您未向我们展示的代码的详细信息,在不使用 SA_RESTART 的情况下安装信号处理程序可能是合适的,以便它中断阻塞的系统调用。
  6. 对此,您唯一需要做的就是确保通信 channel 的每一端都能妥善处理另一端的突然断开连接。
    • 如果这是最终成为网络服务器和客户端的模型,则在开始测试突然断开连接之前,您应该从使用 pipe 更改为使用 socketpair,因为socketpair fds 的行为更像真实的网络套接字。
  7. I/O 开销可能比 malloc 开销大得多。在这个阶段担心 malloc 开销是不成熟的优化。

关于c - 使用 Pipe()、fork() 和信号处理来管理程序中的内存和管道/套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48552242/

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