正确的方法关闭一个阻塞的UDP套接字 [英] Proper way to close a blocking UDP socket

查看:1129
本文介绍了正确的方法关闭一个阻塞的UDP套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C ++对象,创建一个线程从阻塞的UDP套接字读取:

I have a C++ object that creates a thread to read from a blocking UDP socket:

mRunning.store(true);
while (mRunning.load(boost::memory_order_consume)) {
    ...
    int size = recvfrom(mSocket, buf, kTextBufSize , 0,
                        (struct sockaddr *) &packet->mReplyAddr.mSockAddr, (socklen_t*)&packet->mReplyAddr.mSockAddrLen);

    if (size > 0) {
        //do stuff
    }
}
return 0;

(mRunning是boost :: atomic)
对象的析构函数是从另一个线程并执行此操作:

(mRunning is a boost::atomic) The object's destructor is called from another thread and does this:

mRunning.store(false);  
#ifdef WIN32
    if (mSocket != -1) closesocket(mSocket);
#else
    if (mSocket != -1) close(mSocket);
#endif
pthread_join(mThread, NULL);

这似乎工作,但我的一个同事建议,如果recv中断在阅读的东西的中间。这个线程安全吗?关闭阻塞UDP套接字的正确方法是什么? (需要跨平台OSX / Linux / Windows)

This seems to work, but one of my colleagues suggested that there might be a problem if recv is interrupted in the middle of reading something. Is this thread safe? What's the correct way of closing a blocking UDP socket? (Needs to be cross-platform OSX/Linux/Windows)

推荐答案

可能有很多不同的问题。将我的应用程序从一个FreeBSD版本移动到另一个我发现这样的close()在较旧的内核正常工作,只是挂了close()直到从recv()在新的返回。和OSX是FreeBSD基于:)

There could be a lot of different problems. Moving my application from one FreeBSD version to another I found that such close() worked normally on older kernel and just hung close() until something returned from recv() on newer. And OSX is FreeBSD based :)

从不同的线程关闭套接字的可移植方法是创建管道和块不在recv(),但在select()。当你需要关闭套接字,写东西到管道,select()将解除阻塞,你可以安全地做close()。

Portable way of closing sockets from different thread is to create pipe and block not in recv(), but in select(). When you need to close socket, write something to pipe, select() will unblock and you can safely do close().

这篇关于正确的方法关闭一个阻塞的UDP套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆