【问题标题】:How can I exit from a select system call at any random time?如何在任何随机时间退出选择系统调用?
【发布时间】:2015-06-09 13:51:43
【问题描述】:

假设有 2 个线程,T1 和 T2。

T1 正在选择一组套接字并执行相应的读/写操作。 现在,如果线程 T2 想要关闭线程 T1(即加入它),那么如果 T1 在选择系统调用时被阻塞,我该怎么做?如何中断选择调用?

【问题讨论】:

标签: c++ linux network-programming


【解决方案1】:

如果您希望自己在线程 T1 上进行清理,更好的答案是从 T2 向自己发送一个信号(我之前使用过 USR1 信号),这将导致 select() 调用T1 以 EINTR 值返回。

然后您可以检查 EINTR 并知道您需要完成一些清理工作并执行此操作。在我的例子中,我有一个单独的线程在一个无限阻塞的 select() 中等待读取,在一个带有退出标志的 while 循环中。

while ( !exit_flag )
{
    ...
    int select_retval = select( ... );

    switch ( select_retval )
    {
        case EINTR:
            /* clean up */
            break;
        default:
            break;
    }
}

我会从 T2 设置退出标志,然后将信号发送到 T1。然后 T1 将进行清理,然后退出循环。在我的例子中,循环是在 T1 中运行的函数,因此 T1 将结束。

【讨论】:

  • pthread_kill(T1,SIGUSR1);这会将信号 SIGUSR1 发送到 pthread T1。当然,假设您使用的是 pthread。
  • 顺便说一下,我在上面给出的方法中使用了 Linux 下的 boost::threads。我只是使用了较低级别的 pthread_kill() 函数,将 T1.native_handle() 作为第一个参数传递。
  • 非常感谢,我也使用了 boost 线程,但找不到杀死 boost 线程的方法。这很有效。
【解决方案2】:

既然你只是想杀死线程,这应该可以工作。

T1:

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
select(...);

T2:

pthread_cancel(t1);
pthread_join(t1, &retval);

【讨论】:

  • 我正在使用 boost 线程,它不提供任何 api 来杀死线程。
  • 这不是正确的答案,如果你在 T1 中分配一些内存并调用 pthread_cancel(),谁来清理 T1 分配的所有内存?如果您仍然想使用这种方法,那么您应该附加清理例程。检查 pthread_cleanup_push()、pthread_cleanup_pop() 的文档。
猜你喜欢
  • 2011-01-18
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2015-02-01
  • 2011-06-24
  • 1970-01-01
  • 2021-11-07
  • 2017-04-25
相关资源
最近更新 更多