c - 中断正在等待的 accept(),只是改变一个全局变量值

标签 c sockets pthreads signals

我正在为大学做一个项目,一个带有服务器和多个客户端的聊天系统。

在规范文档中写着:

The main thread does a controlled loop on the global var go, and at each cycle waits for a connection request by an user

还有:

Server stops with SIGTERM or SIGINT. When signal is received, the global var go is set to zero, and all threads exit from the loop cycle

因此,thread main 创建套接字,绑定(bind)端口,并在每个新连接处执行 accept() 并创建一个 thread worker 负责与客户的沟通。

我的问题是退出 thread main 只是改变了全局变量。 在 thread main 如果我这样做了

while (go && accept(params)) {}

它不进入 while 循环。

所以现在代码是

while (go) {
    accept(params);
    // Do stuff
}

而且,当我将 go 设置为零时,它会等待 accept,所以我必须创建一个新连接,它接受连接,然后退出线程因为 go 变为零。

thread worker 同样的问题

while (go && read(socket_id, buffer, sizeof(char)) > 0) {}

它等待来自套接字的字符退出循环。

我没有看到仅使用 go var 来退出循环的方法。 我想我必须关闭套接字,或者找到其他方法,我错了吗?

我对退出线程的其他方式不感兴趣,只是想知道是否可以通过更改 go var 来退出循环

谢谢!

最佳答案

假设您为 SIGINTSIGTERM 设置了一个信号处理程序来切换 go!=0 你还想取消设置处理程序的 SA_RESTART 标志,这将使 accept() 在信号接收时返回 -1

为此使用 sigaction() 设置信号处理程序.对于您传入的 struct sigaction,不要将成员 sa_flags 设置为保持 SA_RESTART

有关哪个系统调用受 SA_RESTART 标志影响的详细说明,请参阅“信号处理程序中断系统调用和库函数部分"的 man 7 signal .


独立于此,确保 go 被定义为 sig_atomic_t

关于c - 中断正在等待的 accept(),只是改变一个全局变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30233479/

相关文章:

c# - 将无符号长数组作为 uint[] 从 C dll 返回到 C# 为什么抛出 MarshalDirectiveException 错误?

ios - 有什么方法可以在没有循环的情况下检查指向指针的 bool** 指针是否包含 C 中的真值?

c# - TcpListener.AcceptTcpClient 是否抛出不重要的异常?

c++ - 从 C++ 中的 pthread 创建返回代码是 11

linux - 正确使用在进程间共享的 pthread mutex

c - 在C中处理信号时调用进程的pid不正确

收集值并将其存储在单独的变量中

sockets - IBM Worklight 6.0 - 套接字异常连接重置

Java : How to achieve socket programming functionality with 3rd party API

c - pthread 中的信号处理