8

IDプロセスによって指定されたメイン(のみ)スレッドIDを見つけるのを手伝ってもらえますか?

タスクコンテキスト:実行中のプロセスには(現時点では)ウィンドウはありませんが、(いくつかの)スレッドがあります。

募集:WM_QUITメインスレッドでのみ投稿。

不要:非プライマリスレッドの使用TerminateProcessまたは投稿。WM_QUIT

4

6 に答える 6

7

メインスレッドのスレッドIDを取得するためのはるかに簡単で確実な方法は、メインスレッドが独自のスレッドIDを::GetCurrentThreadId()共有グローバル変数に記録するようにすることです。おそらく、WinMainまたは「メインスレッド」の最初のどこかにあります。

MainThreadId_G = ::GetCurrentThreadId();

次に、他のスレッドで、次のように呼び出すことができます。::PostThreadMessage(MainThreadId_G, WM_QUIT, returncode, 0);

于 2014-05-22T02:40:47.387 に答える
6
#ifndef MAKEULONGLONG
#define MAKEULONGLONG(ldw, hdw) ((ULONGLONG(hdw) << 32) | ((ldw) & 0xFFFFFFFF))
#endif

#ifndef MAXULONGLONG
#define MAXULONGLONG ((ULONGLONG)~((ULONGLONG)0))
#endif

bool CloseProcessMainThread(DWORD dwProcID)
{
  DWORD dwMainThreadID = 0;
  ULONGLONG ullMinCreateTime = MAXULONGLONG;

  HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  if (hThreadSnap != INVALID_HANDLE_VALUE) {
    THREADENTRY32 th32;
    th32.dwSize = sizeof(THREADENTRY32);
    BOOL bOK = TRUE;
    for (bOK = Thread32First(hThreadSnap, &th32); bOK;
         bOK = Thread32Next(hThreadSnap, &th32)) {
      if (th32.th32OwnerProcessID == dwProcID) {
        HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,
                                    TRUE, th32.th32ThreadID);
        if (hThread) {
          FILETIME afTimes[4] = {0};
          if (GetThreadTimes(hThread,
                             &afTimes[0], &afTimes[1], &afTimes[2], &afTimes[3])) {
            ULONGLONG ullTest = MAKEULONGLONG(afTimes[0].dwLowDateTime,
                                              afTimes[0].dwHighDateTime);
            if (ullTest && ullTest < ullMinCreateTime) {
              ullMinCreateTime = ullTest;
              dwMainThreadID = th32.th32ThreadID; // let it be main... :)
            }
          }
          CloseHandle(hThread);
        }
      }
    }
#ifndef UNDER_CE
    CloseHandle(hThreadSnap);
#else
    CloseToolhelp32Snapshot(hThreadSnap);
#endif
  }

  if (dwMainThreadID) {
    PostThreadMessage(dwMainThreadID, WM_QUIT, 0, 0); // close your eyes...
  }

  return (0 != dwMainThreadID);
}
于 2013-03-24T10:07:02.190 に答える
2

これがMFCでどのように処理されるかを確認しましたが、UIスレッドはコンストラクターから決定されているようです。

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\src\mfc\appcore.cpp:

CWinApp::CWinApp(LPCTSTR lpszAppName)
{
...

    m_nThreadID = ::GetCurrentThreadId();

また、MFC呼び出しAfxGetApp()->m_nThreadIDを使用すると、UIスレッドIDを把握できます。

ただし、.dllがメインスレッドからロードされていない場合、このアプローチは機能しません。MFCのアプローチでも機能しませんAfxGetApp()->m_nThreadID。メインスレッド以外のものが返されます。

ただし、通常、.dllはメインスレッドから読み込まれますが、.dllをmfcで有効にする必要はありません。私はこのようなアプローチをお勧めすることができます:

class GetMainThread
{
public:
    GetMainThread()
    {
        m_nThreadID = ::GetCurrentThreadId();
    }

    DWORD m_nThreadID;
}getMainThread;


DWORD getUIThread()
{
    DWORD id = 0;

    if( AfxGetApp() != NULL )
        id = AfxGetApp()->m_nThreadID;
    else 
        id = getMainThread.m_nThreadID;

    return id;
} //getUIThread

.dllがメインUIスレッドによってロードされる場合、コンストラクター呼び出し(GetMainThreadクラス)から正しいスレッドIDを取得します。

AfxGetApp()必要がない場合は電話を削除します(私のアプリケーションではそれらが必要でした)

于 2016-08-25T09:49:14.853 に答える
1

関数ではなく、cppファイルの先頭でこれを使用します。

DWORD mainThreadID = ::GetCurrentThreadId();

これにより、メイン関数が実行される前にmainThreadIDが初期化され、メインスレッドであることが保証されます。

于 2020-06-24T20:32:14.670 に答える
0

特定のスレッドにメッセージを投稿することはできません。メッセージはキューに入れられ、メインスレッドからのみ処理されます。

UIを備えたWindowsプロセスを閉じる場合は、sendmessageを使用してwm_closeを別のプロセスに送信する方法を確認してください。

于 2013-03-24T10:05:26.400 に答える
0

この関数を探しますか:

DWORD WINAPI GetProcessIdOfThreadId(_In_ DWORD ThreadId)
{
    HANDLE Thread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, ThreadId);
    DWORD process_id = GetProcessIdOfThread(Thread);
    CloseHandle(Thread);
    return process_id;
}
于 2018-06-25T16:31:15.397 に答える