使用fork
,pipe
和signal.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
}
有些让我困惑的事情:
close()
信号处理程序中的pipe
吗?free()
之后write()
缓冲区吗?is_shutdown
标志和进程间通信。我是否理解父母和孩子不会将is_shutdown
作为同一个变量(他们是副本)共享,而改变为另一个不会改变另一个?is_shutdown
的{{1}}进行并发访问怎么样?任何隐藏的细节,如通过多线程并发?main
都不是明智之举。但是定义“足够大”的缓冲区感觉就像一个黑客(如果有一天它不够大的话)。我错了吗?我对C及其内存和资源管理都很陌生:从基于强大的英特尔服务器/台式机的C ++ 14开发切换到~180MHz ARM嵌入式系统的C开发,所以我可能会担心很多而忘记一些明显的的东西。
答案 0 :(得分:1)
is_shutdown
。write
制作副本。在write
返回后,重用或取消分配缓冲区是安全的。 (但一定要处理短写。)is_shutdown
。在while循环终止后,在parent
和child
块中清理。is_shutdown
需要使用类型volatile sig_atomic_t
声明,对于像这样的简单程序,它不应该被信号处理程序以外的任何东西写入。此外,信号处理程序不应读取其值,它应该只设置它。根据您尚未向我们展示的代码的详细信息,在不使用SA_RESTART
的情况下安装信号处理程序可能是合适的,这样就可以中断阻塞系统调用。pipe
更改为使用socketpair
,因为socketpair
fds表现得更像真正的网络套接字。