C-向另一个线程发送清除和退出的信号
我保证这不是家庭作业问题 我正在编写一个时间序列数据库实现,作为学习C语言的一种方法 我已经编写了一对客户机/服务器。服务器当前是侦听端口上套接字的echo服务器。客户端连接到该端口并向其发送输入行。它使用C-向另一个线程发送清除和退出的信号,c,sockets,pthreads,signals,C,Sockets,Pthreads,Signals,我保证这不是家庭作业问题 我正在编写一个时间序列数据库实现,作为学习C语言的一种方法 我已经编写了一对客户机/服务器。服务器当前是侦听端口上套接字的echo服务器。客户端连接到该端口并向其发送输入行。它使用readline获取输入,将其发送到客户端套接字,recv从客户端套接字接收一行,并将该行打印到终端。冲洗,重复。当客户端从recv获得EOF时返回,此时它知道连接已关闭 问题是,readline正在阻塞,因此,如果服务器进程被终止,即iSIGINT它,客户端仍在readline上阻塞。直到它
readline
获取输入,将其发送到客户端套接字,recv
从客户端套接字接收一行,并将该行打印到终端。冲洗,重复。当客户端从recv
获得EOF
时返回,此时它知道连接已关闭
问题是,readline
正在阻塞,因此,如果服务器进程被终止,即iSIGINT
它,客户端仍在readline
上阻塞。直到它发送
s,然后再接收s和EOF之后,它才知道服务器已经不在了
我希望发生的是,如果recv
上出现EOF
,客户机会收到信号,并立即退出
我想我需要做的是为网络客户端(send
和recv
)创建3个pthreads
-2个,为终端创建1个。终端调用readline
并阻塞。它接受输入,然后使用pthread\u cond\t
向等待发送的网络客户端send
线程发送信号。网络客户端recv
线程不断地recv
ing,这将导致阻塞。如果它是一个EOF
,它会引发SIGINT
,处理程序pthread\u kill
s所有3个线程,fprintf
s类似于“服务器关闭连接”,并调用exit
(是的,我知道exit
无论如何都会终止所有线程-这是一个清洁练习,看看我是否理解C)
这是正确的方法吗?显然,网络客户端终端一直在这样做。正确的方法是什么?如果我理解正确,您希望在服务器死机时,在
write()
/send()
之前的readline期间退出。你的方法很好。如果服务器已死机,您将捕获的唯一方法是当您尝试write()
/send()
时,您将得到一个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;
}
/**
*从文件描述符fd中读取一行的简单实用程序函数,
*最多maxlen字节——摘自Unix网络编程,Stevens。
*/
int
读线(int-fd,char*buf,int-maxlen)
{
int n,rc;
字符c;
对于(n=1;n
这个问题以前已经回答过了。我让Stevens和第5章建议将readline
调用与套接字read
交错,以查找EOF
。我在谷歌上搜索了libreadline
和select
/poll
,看到了以下内容:
有一种方法可以使用交错I/O,因此libreadline
不只是阻塞:
感谢@arayq2和@G--推荐史蒂文斯 没有一种正确的方法。经典参考是Rich Stevens的@arayq2谢谢!我去看看!“它使用readline获取输入…”“它”是谁、客户机还是服务器?而且:我们不发送“到套接字”,而是通过“套接字”发送到某个目的地(这里客户机就是服务器),因为套接字主要是双向使用的。这是有道理的。FWIW的一位同事说,为每个字符调用read
效率很低,因为每个调用都必须被内核捕获。我不知道这是不是真的,如果是,会有什么影响。无论如何,我实际上是在使用libreadline
来获得内置的ctrl字符功能。我去看看史蒂文斯。