这类似于Proper way to close a blocking UDP socket的问题。我有一个线程在C从UDP套接字读取。读取被阻止。我想知道是否有可能能够退出线程,而不依赖recv()返回?例如,我可以关闭另一个线程的套接字,并安全地期望套接字读取线程退出吗?没有看到任何高线投票答案,这就是为什么我再次问。试图从阻止UDP套接字退出阅读
回答
这真的取决于你在哪个系统下运行。例如,如果您在符合POSIX的系统下运行并且线程可以取消,那么当您取消线程时,recv()调用将被中断,因为它是一个取消点。
如果你使用的是老式插座实现,你可以设置你的线程像SIGUSR1并希望大家都不信号处理其他任何人想它和信号,因为的recv()将中断的信号。如果可能的话,你最好的选择是不要阻塞。
我不认为关闭参与阻塞操作插座是终止操作的安全保障方式。例如,kernel.org警告黑暗:
这可能是不明智的关闭文件描述符,而他们可能会在 通过使用在同一过程中的其他线程的系统调用。由于 文件描述符可能会被重复使用,有一些模糊的竞争条件 可能会导致意想不到的副作用。
相反,你可以使用一个信号,使
recv
失败,EINTR
(确保未启用SA_RESTART
)。您可以将信号发送到 特定线程与pthread_kill
您可以启用插槽上
SO_RCVTIMEO
开始的recv 调用之前
个人而言,我通常会尽量避开所有的信号污秽的,但是这是一个可行的选择。
+1为kernel.org警告.. – jogabonito
你有一对夫妇的该选项。信号会中断读取操作,所以您只需确保信号消失即可。 recv操作应该失败,错误编号为EINTR。
最简单的方法是设置一个计时器超时一些例如之后中断自己的过程30秒:
itimerval timer
timeval time;
time.tv_sec = 30;
time.tv_usec = 0;
timer.it_value = time;
if(setitimer(ITIMER_REAL, &timer, NULL) != 0)
printf("failed to start timer\n");
你会在指定时间后得到一个SIGALRM,这会打断你的阻塞操作,给你重复操作或退出的机会。
,而另一个线程是不能解除分配共享资源,也可能使用它。在实践中,你会发现你甚至无法编写代码来执行你的建议。
想一想。当你去打电话close
,你怎么可能知道另一个线程实际上被阻止在recv
?如果它要调用recv
,但是接着另一个线程调用socket
并获取刚才关闭的描述符?现在,该线程不但不会检测到任何错误,而且还会在错误的套接字上调用recv
!
可能有一个很好的方法来解决你的外部问题,你需要退出阻塞UDP套接字读取的原因。也有几个丑陋的黑客可用。基本的方法是使套接字非阻塞,而不是阻塞UDP套接字读取,伪造阻塞读取select
或poll
。然后你可以用几种方法中止这个循环:
一种方法是select
超时并在select
返回时检查'abort'标志。
另一种方法是在管道的读取端也是select
。发送一个字节到管道来中止select
。
如果POSIX complient系统,你可以尝试监视你的线程: 在pthread_create与功能,使你的的recv和pthread_cond_signal会刚过,然后返回。
调用线程使pthread_cond_timedwait具有所需的超时值,并在timed_out时终止被调用的线程。
- 1. 尝试从UDP套接字读取时出错
- 2. Python套接字接受块 - 阻止应用程序退出
- 3. Tcp套接字读取总是阻止
- 4. 读取数据从UDP套接字
- 5. Java:阻止套接字抛出EOFException
- 6. 杀死一个被阻止的UDP套接字
- 7. udp套接字停止接收数据
- 8. Android非阻塞从套接字读取
- 9. c#套接字阻止
- 10. 阻止从输入TCP套接字读取
- 11. UDP套接字
- 12. 退出阅读erb
- 13. UDP-无法从python中读取字节从套接字?
- 14. 停止UDP套接字服务器
- 15. 套接字UDP程序在recvfrom停止
- 16. NS-3 TCP/UDP套接字是非阻塞还是阻塞?
- 17. 从读取连接的udp套接字返回c
- 18. Phonegap UDP套接字?
- 19. MessageBox阻止从应用程序退出
- 20. 从阻止进程中优雅退出
- 21. C - 从UDP套接字缓冲区(Linux)读取字节
- 22. 如何终止非阻塞套接字连接尝试?
- 23. golang - 阻止应用退出
- 24. 阻止UDP转发
- 25. PHP套接字写入然后读取阻塞套接字
- 26. 套接字Winsock异步阻止同时读写
- 27. C#套接字阻止行为
- 28. 阻止代理使用的套接字
- 29. 阻止套接字和选择
- 30. Java nextLine在套接字上被阻止
取消似乎是一个有前途的想法。线程的取消点是否有任何文档可用?我看到[链接](http://www.mkssoftware.com/docs/man3/pthread_cancel.3.asp)它没有列出任何套接字相关的调用。或者'recv()'反过来使用'read()'等其他调用,例如 – jogabonito
@jogabonito如果你的系统符合posix并且使用符合posix的套接字,它将会是。 [posix取消点数](http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_05_02) –