C-向另一个线程发送清除和退出的信号

C-向另一个线程发送清除和退出的信号,c,sockets,pthreads,signals,C,Sockets,Pthreads,Signals,我保证这不是家庭作业问题 我正在编写一个时间序列数据库实现,作为学习C语言的一种方法 我已经编写了一对客户机/服务器。服务器当前是侦听端口上套接字的echo服务器。客户端连接到该端口并向其发送输入行。它使用readline获取输入,将其发送到客户端套接字,recv从客户端套接字接收一行,并将该行打印到终端。冲洗,重复。当客户端从recv获得EOF时返回,此时它知道连接已关闭 问题是,readline正在阻塞,因此,如果服务器进程被终止,即iSIGINT它,客户端仍在readline上阻塞。直到它

我保证这不是家庭作业问题

我正在编写一个时间序列数据库实现,作为学习C语言的一种方法

我已经编写了一对客户机/服务器。服务器当前是侦听端口上套接字的echo服务器。客户端连接到该端口并向其发送输入行。它使用
readline
获取输入,
将其发送到客户端套接字,
recv
从客户端套接字接收一行,并将该行打印到终端。冲洗,重复。当客户端从
recv
获得
EOF
时返回,此时它知道连接已关闭

问题是,
readline
正在阻塞,因此,如果服务器进程被终止,即i
SIGINT
它,客户端仍在
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字符功能。我去看看史蒂文斯。