[英]C - Signaling to another thread to cleanup and exit
我保证,这不是作业问题。
我正在编写时间序列数据库实现作为学习C的方法。
我已经编写了一个客户机/服务器对。 该服务器当前是侦听端口上的套接字的回显服务器。 客户端连接到该端口并向其发送输入行。 它使用readline
获取输入, send
其send
到客户端套接字,从客户端套接字recv
一行,并将该行打印到终端。 冲洗,重复。 客户端从recv
获得EOF
时返回,此时客户端知道连接已关闭。
问题是readline
处于阻塞状态,因此,如果服务器进程被杀死,即我对它进行了SIGINT
处理,则客户端仍在readline
上处于阻塞状态。 直到它send
s,然后recv
一个EOF
之后,它才知道服务器已消失。
我想发生的事情是,如果recv
上有EOF
,则客户端会收到信号并立即退出。
我想我需要做的是创建3个pthreads
-2个用于网络客户端( send
和recv
),1个用于终端。 终端调用readline
和block。 它接受输入,然后使用pthread_cond_t
通知正在等待网络客户端send
线程发送。 网络客户端recv
线程一直在recv
,这将阻塞。 如果它是EOF
,它将引发SIGINT
, pthread_kill
所有3个线程处理到该处理器, fprintf
类似于“服务器关闭连接。”,然后调用exit
(是的,我知道exit
无论如何都会终止所有线程-这是一个练习清洁,看看我是否理解C)。
这是合适的方法吗? 显然,网络客户终端一直在这样做。 什么是正确的方法?
如果我对您的理解正确,那么您希望在服务器退出后的readline
(在write()
/ send()
之前write()
退出。 您的方法很好。 如果服务器已死,您将捕获的唯一方法是,当您尝试执行write()
/ send()
您将获得SIGPIPE
,它将在SIGPIPE
其后导致退出。 因为默认情况下,除非有要发送或确认的数据,否则不会在连接上发送任何数据包。 因此,如果您只是在等待来自对等方的数据,则无法判断对等方是否已经静默离开,或者还没有准备好发送或接收更多数据。 因此,您将需要在单独的线程中为SIGPIPE
一些轮询器,并在获取时退出。 您可以使用此readline
功能来帮助您开始进行检查。
/**
* Simple utility function that reads a line from a file descriptor fd,
* up to maxlen bytes -- ripped from Unix Network Programming, Stevens.
*/
int
readline(int fd, char *buf, int maxlen)
{
int n, rc;
char c;
for (n = 1; n < maxlen; n++) {
if ((rc = read(fd, &c, 1)) == 1) {
*buf++ = c;
if (c == '\n')
break;
} else if (rc == 0) {
if (n == 1)
return 0; // EOF, no data read
else
break; // EOF, read some data
} else
return -1; // error
}
*buf = '\0'; // null-terminate
return n;
}
这个问题已经回答过了。 我得到了史蒂文斯(Stevens)的帮助,第5章建议将readline
调用与套接字read
插入,以查找EOF
。 我在Google搜索libreadline
并select
/ poll
,结果如下:
有一种使用交错I / O的方法,因此libreadline
不仅会阻塞:
http://www.delorie.com/gnu/docs/readline/rlman_41.html
感谢@ arayq2和@ G--建议史蒂文斯!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.