【问题标题】:Interrupt a accept() that is waiting, just changing a global variable value中断一个正在等待的accept(),只是改变一个全局变量值
【发布时间】:2015-07-25 20:12:31
【问题描述】:

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

在规范文件中有这样写:

主线程在全局 var go 上做一个受控循环,并在每个循环中等待用户的连接请求

还有:

服务器以 SIGTERM 或 SIGINT 停止。接收到signal时,全局var go置零,所有线程退出循环循环

因此,thread main 创建套接字、绑定端口并在每个新连接处执行一个 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 来退出循环

谢谢!

【问题讨论】:

  • listen 不会阻止。你的意思是accept
  • @immibis 对,对不起,让我更新问题。完成
  • 如何切换go
  • @alk 我在 main() 函数中有一个信号处理程序。它运作良好,因为当我将它设置为 0 其他时(去)(里面没有接受或读取)退出

标签: c sockets pthreads signals


【解决方案1】:

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

为此,请使用sigaction() 设置信号处理程序。对于您传入的struct sigaction,请勿将成员sa_flags 设置为持有SA_RESTART

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


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

【讨论】:

  • 哇,谢谢!我从这个答案中学到了很多 :-) 它确实很好用,而且我还有新的东西要阅读和学习!再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
相关资源
最近更新 更多