суббота, 10 апреля 2010 г.

CreateToolhelp32Snapshot и многопоточность

   В процессе поиска причины, по который программа аварийно завершается с ошибкой (другими словами просто вылетает), возникло предположение, что функция CreateToolhelp32Snapshot потоко-небезопасна.

   И вскоре правильность этого предположения была подтверждена - благодаря найденному комментарию к этой функции из исходников Windows 2000 (которые гуляют в интернете).

HANDLE
WINAPI
CreateToolhelp32Snapshot(
    IN DWORD dwFlags,
    IN DWORD th32ProcessID)
/*++

Routine Description:

    Takes a snapshot of the Win32 processes, heaps, modules, and threads used
    by the Win32 processes. Returns an open handle to the specified snapshot if
    successful or  -1 otherwise.

    NOTE that all of the snapshots are global except for the heap and module
    lists which are process specific. To enumerate the heap or module state for
    all WIN32 processes call with TH32CS_SNAPALL and the current process. Then
    for each process in the TH32CS_SNAPPROCESS list that isn't the current
    process, do a call with just TH32CS_SNAPHEAPLIST and/or TH32CS_SNAPMODULE.

    Use CloseHandle to destroy the snapshot

    This function is not multi-thread safe.  All of the other functions are.

Arguments:

    dwFlags - Supplies switches to specify action as follows:
        TH32CS_INHERIT  Indicates that the snapshot handle is to be inheritable.
        TH32CS_SNAPALL  Equivalent to specifying the TH32CS_SNAPHEAPLIST,
                        TH32CS_SNAPMODULE, TH32CS_SNAPPROCESS, and
                        TH32CS_SNAPTHREAD values.
        TH32CS_SNAPHEAPLIST     Includes the heap list of the specified Win32
                                process in the snapshot.
        TH32CS_SNAPMODULE       Includes the module list of the specified Win32
                                process in the snapshot.
        TH32CS_SNAPPROCESS      Includes the Win32 process list in the snapshot.
        TH32CS_SNAPTHREAD       Includes the Win32 thread list in the snapshot.

    th32ProcessID - Supplies a Win32 process identifier. This parameter can be
        zero to indicate the current process. This parameter is used when the
        TH32CS_SNAPHEAPLIST or TH32CS_SNAPMODULE value is specified. Otherwise,
        it is ignored. The snapshot taken by this function is examined by the
        other tool help functions to provide their results.  Access to the
        snapshot is read only. The snapshot handle acts like a Win32 object
        handle and is subject to the same rules regarding which processes and
        threads it is valid in.

Return Value:

    Returns an open handle to the specified snapshot if successful or -1 if not.
    To retrieve an extended error status code generated by this function, use
    the GetLastError function.
    To destroy the snapshot, use the CloseHandle function.

--*/

   Мораль сей басни такова: если в приложении есть потенциальная возможность вызова CreateToolhelp32Snapshot из разных потоков, то надо этот вызов защищать критической секцией (собственно таким способом и была решена проблема вылетов проблемного приложения).

   Остальные же функции Tool Help можно вызывать, не заботясь о синхронизации.

Комментариев нет:

Отправить комментарий