atExit関数でWSACleanupを登録することはできますか?コード内のさまざまな箇所で終了できるいくつかのアプリケーションがありますので、WSACleanupをコードを徹底して使用することは避けてください。これらすべてのアプリケーションで使用されているdllがあるので、Creatntly DllMainを使用してWSAStartup/WSACleanupを呼び出します。ただし、Microsoftでは、デッドロックの原因となる可能性があるため、DllMainを使用してWSAStartup/WSACleanupを使用することについて厳密にアドバイスしています。 WSAStarupをDllMainから移動して、Windowsソケットライブラリにアクセスする前に、すべてのアプリケーションのコードの一箇所でこれを呼び出すことができます。そして、WSAStartupを呼び出すとすぐに、atExit関数を使用してWSACleanupへの呼び出しを登録したいと考えています。誰もがこのアプローチの経験がありますか?ありがとう!WSACleanupとatExit
答えて
マルチスレッドアプリケーションがあり、スレッドのいくつかがまだ接続されている場合、相手側のアプリケーションは接続が終了する方法が気に入らない場合があります。ですから、main()が終了する前に順序付けられた方法ですべての通信を終了し、終了したらWSACleanupを呼び出すことができます。
まあ、atExitは使用しないでください。クラス内のソケットライブラリの初期化と破壊のラッピングのRAII原則に従うべきです。
私はRAIIアプローチが好都合であることに同意します。
しかし、警告の単語:dllとハンドルが混在したatExitは、ウィンドウで壊れています。残念ながら、これはRAIIにも影響します。これは、C++ランタイムによってatExitハンドラで実装されるためです。
のatexitハンドラがウィンドウで呼び出される順序:
- どこかに出口が(呼ばまたはメインれる)は、プロセスで定義された
- のatexitハンドラが呼び出されるスコープの外に出ます。
- すべてのハンドルが破棄されます。
- dllで定義されたatexitハンドラが呼び出されます。
のDLL内のatexitハンドラは、プロセスハンドラが最初に呼び出され、DLLのハンドラが呼び出される前にハンドルが破棄されている過程でのハンドラの前に登録されている場合、それは問題ではありません。これにより、DLLによって所有されているすべてのハンドルが無効になったため、クリーンアップコードが呼び出されたときにwin32の例外が発生します。
スレッド、ミューテックス、ファイル、ソケットなどにハンドルを保持するコードです。これらがdllに割り当てられている場合は、exitを呼び出す前にクリーンナップする必要があります。
私は間違っている場合や、誰かがこれを回避する方法を知っていれば、私はこれがアプリケーションのクリーンアップに尽きない痛みを引き起こすので、私が知りたいと思っています。私は、アプリケーションが終了したときにwin32の例外を受け取った後で、これをC++ランタイムのデバッグ出口処理と考えました。
コードを終了するためにすべての呼び出しを削除する必要がありました。私は今、dllの静的データがハンドルを制御しないようにしました。すべての静的ハンドルは、メインがスコープ外になると破壊されるオブジェクトによって制御されます。
壊れていません。 EXEからのグローバルdtorsの前にDLLをアンロードした場合、そのdtorから関数を呼び出すときにアプリケーションのdtorが失敗します。現在のセットアップでは、EXEはDLLに依存することができますが、逆もありません。 また、DLLMainのハンドルを開いたり閉じたりしないでください。これは新しいルールではありません。 AtExit処理はDLLMainの一部であるため、これらのルールを継承します。 すばやい解決策は、すべてのDLLリソースにスマートポインタを使用することです。アプリケーションがDLLリソースへの最後のスマートポインタをクリーンアップすると、DLLはクリーンアップ可能であり、これはAtExitの前であることを認識します。 – MSalters
DLLMainのメモをありがとう、私はこれを実現しませんでした。スマートポインタ上のメモ:これはmainまたはそれ以下で宣言され、静的ではない場合にのみ有効です。 – iain
私はまだそれを行う正しい方法を取得していません。特定の機能を提供するDLLを持っているとどうなりますか? DLLを読み込んで特定の関数(内部的にWinsock APIにアクセスする)を呼び出すアプリケーションでは、WSAStartupを少なくとも1回呼び出さなければなりません。これらの関数をすべてクラスにラップして、WSAStartupが少なくとも一度呼び出されるようにすることができます。アプリケーションはいつでも終了することができ、WSACleanupを呼び出す唯一の方法は、a)atExitまたはb)グローバルデストラクタを使用することです。私が理解したところでは、どちらも問題を引き起こす可能性があります。これの方法は何ですか? –
- 1. Pythonマルチプロセッシングatexitエラー "atexit._run_exitfuncsのエラー"
- 2. atexitに値を渡す
- 3. atexit、Cで代理人を終了
- 4. on_exit()関数とatexit()関数に違いはありますか?
- 5. 「ノーモジュールという名前のatexit」私はすべてのpyInstallerの
- 6. atexit()で登録された関数で終了コードを変更することはできますか? <a href="http://linux.die.net/man/3/atexit" rel="noreferrer"><code>atexit(3)</code></a>ため
- 7. atexit()に登録されている関数が
- 8. atexitは他のスレッドが死ぬのを待ちますか?
- 9. 登録されたatexit関数でエラートレースバックを取得する
- 10. Pythonのマルチプロセッシングサブプロセスで "atexit"関数を登録するには?
- 11. 混在モードのC++/CLIクラッシュ:atexitのヒープ破損(静的デストラクタ登録)
- 12. atexit()経由で登録された関数への参照を取得する
- 13. 実行時にロードされるdll/atexのatexit()の振る舞いは何ですか?
- 14. atexitコールバックがPythonで呼び出されたときに終了コードまたは理由を見つける方法はありますか?
- 15. WinsockサーバーとクライアントC++コード - getaddrinfoがこのスコープで宣言されていません
- 16. クライアントサーバーVisual C++での通信ソケットプログラミング
- 17. gethostbyaddr()にエラーがあります11001
- 18. どうすればいつでもサーバーを開くことができますか?
- 19. シンプルなHTTPクライアントC用のrecv()ブロック
- 20. C#ソケットとC#サーバの接続
- 21. C++ソケット誤ったコマンドを受信しました。意図していません
- 22. winsockを使用してローカルホストの内容を取得する
- 23. 10038(WSAENOTSOCK)のエラーを返すバインドメソッド
- 24. 実行中のLinuxプロセスを中断して終了すると、どのようなクリーンアップルーチンが実行されますか?
- 25. getaddrinfo()へのすべての呼び出しで11001が返されました
- 26. winsockクライアントとサーバーの通信
- 27. 誰でも私を案内したり、HTTP経由でストリーミングするライブメディアサーバーのクライアントを作成する方法を提案することができます
- 28. はどのようにC++
- 29. クライアントからサーバーまでの遅延見積もり-
- 30. winsockサーバーのトラブルシューティング
いいスタイルですが、これは1つのイオタを助けません。プロセスの観点から、atexit()処理はグローバルデストラクタの実行と同時に行われます。 AtExitからWSACleanupを呼び出す際に問題が発生しても、あなたは依然としてdtorからwhanを呼び出している可能性があります。 – MSalters