C++ WSACleanup和atExit
通过atExit函数注册WSACleanup可以吗?我们有几个应用程序可以在代码中的不同点终止,因此我们希望避免在代码中到处使用WSACleanup。目前,我们通过DllMain调用WSAStartup/WSACleanup,因为我们有一个供所有这些应用程序使用的dll。但是,Microsoft严格建议不要通过DllMain使用WSAStartup/WSACleanup,因为这可能导致死锁。我们可以将WSAStarup移出DllMain,并在所有应用程序访问Windows sockets库之前,在代码中的某一点调用它。而且,只要调用WSAStartup,我们就希望使用atExit函数注册对WSACleanup的调用。有没有人有过这种方法的经验?谢谢 如果您有一个多线程应用程序,但其中一些线程仍处于连接状态,则另一端的应用程序可能不喜欢终止连接的方式。因此,最好在main()终止之前以有序的方式关闭所有通信,这样做之后,您就可以调用WSACleanup了。我认为不应该使用atExit。您应该遵循RAII原则,将套接字库的初始化和销毁包装在一个类中。我同意RAII方法是有利的 然而,有一句话要警告:atExit与DLL和句柄混合在一起在windows上被破坏。不幸的是,这也影响了RII,因为这是用C++运行时执行的ATExter处理程序实现的。 在windows上调用atexit处理程序的顺序:C++ WSACleanup和atExit,c++,winsock,atexit,wsastartup,wsacleanup,C++,Winsock,Atexit,Wsastartup,Wsacleanup,通过atExit函数注册WSACleanup可以吗?我们有几个应用程序可以在代码中的不同点终止,因此我们希望避免在代码中到处使用WSACleanup。目前,我们通过DllMain调用WSAStartup/WSACleanup,因为我们有一个供所有这些应用程序使用的dll。但是,Microsoft严格建议不要通过DllMain使用WSAStartup/WSACleanup,因为这可能导致死锁。我们可以将WSAStarup移出DllMain,并在所有应用程序访问Windows sockets库之前,
我必须删除所有调用才能从代码中退出。我现在确保dll中没有静态数据控制句柄。所有静态句柄都由对象控制,当main超出范围时,这些对象将被销毁。虽然样式很好,但这一点都没有帮助。从流程的角度来看,atexit()处理与全局析构函数的运行同时进行。从AtExit调用WSACleanup时遇到的任何问题,您可能仍然会遇到whan从dtor调用它的问题,而不是崩溃。如果从EXE中在全局dtor之前卸载DLL,则从该dtor调用函数时,应用程序中的任何dtor都将失败。当前的设置允许EXE依赖DLL,但不能反过来。此外,您不应该在DLLMain中打开或关闭句柄,这不是新规则。AtExit处理是DLLMain的一部分,因此它继承了这些规则。一个快速的解决方案是对所有DLL资源使用智能指针。当应用程序清理其指向DLL资源的最后一个智能指针时,DLL将知道它可以清理,这是在AtExit之前。感谢DLLMain上的注释,我没有意识到这一点。您在智能指针上的注意事项:只有在main或bellow中声明它而不是静态的情况下,这才有效,对吗?我仍然没有正确的方法来执行它。如果我有一个提供特定功能的DLL呢。加载DLL并调用某些函数(在内部访问Winsock API)的应用程序需要至少调用一次WSAStartup。我可以将所有这些函数封装到一个类中,并确保至少调用一次WSAStartup。现在,应用程序可以在任何时间点退出,我看到调用WSACleanup的唯一方法是a)通过atExit或b)通过全局Destructor。据我所知,两者都会引起问题。有什么出路?