可以通过atExit函数注册WSACleanup吗?我们有几个应用程序可以在代码中的不同位置终止,所以我们希望避免将WSACleanup放在代码中的任何地方。目前我们通过DllMain调用WSAStartup / WSACleanup,因为我们有一个供所有这些应用程序使用的动态链接库。然而,微软严格建议不要通过DllMain使用WSAStartup / WSACleanup,因为这可能会导致死锁。我们可以将WSAStarup移出DllMain,并在所有应用程序访问Windows socket库之前在代码中调用它。而且,只要我们调用WSAStartup,我们就希望使用atExit函数来注册对WSACleanup的调用。有没有人有过这种方法的经验?谢谢!
发布于 2009-06-09 09:10:11
如果您有一个多线程应用程序,并且某些线程仍在连接中,则另一端的应用程序可能不会喜欢终止连接的方式。因此,最好在main()终止之前以有序的方式关闭所有通信,这样做之后,就可以调用WSACleanup了。
发布于 2009-06-10 14:09:06
我同意RAII方法是有利的。
然而,一句警告:混合了dlls和句柄的atExit在windows上被破坏了。不幸的是,这也会影响RAII,因为这是由c++运行时使用atExit处理程序实现的。
在windows上调用atexit处理程序的顺序:
如果dll中的atexit处理程序是在进程中的处理程序之前注册的,那么进程处理程序将首先被调用,而句柄在dll处理程序被调用之前被销毁。当调用清理代码时,这会导致win32异常,因为all拥有的所有句柄都不再有效。
这会影响保存线程、互斥锁、文件、套接字等句柄的代码。如果它们是在dll中分配的,则必须在调用exit之前清除它们,否则根本不会调用。
顺便说一句,我不是反窗口,如果我错了,或者任何人知道这一点,我很想知道,因为这给我在应用程序清理中带来了无尽的痛苦。在应用程序退出时获得win32异常后,我通过在c++运行时调试退出处理解决了这一问题。
我必须删除所有的调用才能退出我的代码。我现在确保了dll中的静态数据不会控制句柄。所有静态句柄都由当main超出作用域时被析构的对象控制。
发布于 2009-06-09 10:23:37
嗯,我认为不应该使用atExit。你应该遵循RAII原则,在一个类中封装初始化和销毁套接字库。
https://stackoverflow.com/questions/968838
复制相似问题