c - Windows 线程 - 调试工作版本没有 - 尝试在线程启动时从线程获取值

标签 c windows multithreading winapi visual-studio-2008

我正在尝试获取线程的 ID 以存储在线程列表中。

为此,我启动了一个线程,该线程带有一个指向将存储线程 ID 的 long 指针。一旦线程函数执行,线程 ID 就应该被存储。存储 ID 后,启动功能应该能够继续。

这段代码似乎只能在 Debug 模式下工作,但在 Release 模式下会挂起。我正在使用 Visual C++ 2008 Express。

我需要代码在 Windows XP 上运行,所以不幸的是我不能简单地使用 GetThreadId,因为它只在 Windows Server 2003 和更新版本上受支持。

thread_wrapper* spawn_thread(void *entryPoint, void *params)
{
    thread_wrapper *newThread = calloc(1, sizeof(thread_wrapper));

    _beginthread(spawned_thread_wrapper_func, 0, &newThread->_win32ThreadID);

    while (newThread->_win32ThreadID == 0) ; // Hangs here in Release mode

    ... // Safely add thread to list using critical section

    return newThread;
}

void spawned_thread_wrapper_func(void *params)
{
    long *outThreadIDPtr = (long *)params;
    *outThreadIDPtr = GetCurrentThreadId();

    // spawn_thread function should now be able to add thread to list
    // but still hangs on while waiting loop in Release mode.
    // Works fine in Debug mode.

    ...
}

这里出了什么问题?

最佳答案

如果您想要该成员变量中的当前线程 ID,这是一种使用 _beginthreadex() 的方法。该 api 使您可以更好地控制线程创建过程,并在需要时提供用于检测线程终止的可等待句柄。请注意,线程过程的原型(prototype)和下面的实现更改很重要。

thread_wrapper* spawn_thread(void *entryPoint, void *params)
{
    thread_wrapper *newThread = calloc(1, sizeof(thread_wrapper));

    // hThread is an OS thread handle you can wait on with 
    // wait functions like WaitForSingleObject.
    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, 
            spawned_thread_wrapper_func, newThread,
            CREATE_SUSPENDED, &newThread->_win32ThreadID);

    // TODO: add new thread (which is created, but not started yet)
    //  to your list.


    // now resume the thread.
    ResumeThread(hThread);

    // if you don't need this any longer, close it, otherwise save it
    //  somewhere else (such as *before* the resume above, you can save
    //  it as a member of your thread_wrapper). No matter what, you have
    //  to close it eventually

    // CloseHandle(hThread);

    return newThread;
}

// note return value difference when using _beginthreadex.
unsigned int _stdcall spawned_thread_wrapper_func(void *params)
{
    thread_wrapper* p = params; // note: with MS you may have to cast this.

    // spawn_thread function should now be able to add thread to list
    // but still hangs on while waiting loop in Release mode.
    // Works fine in Debug mode.

    ...
}

关于c - Windows 线程 - 调试工作版本没有 - 尝试在线程启动时从线程获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18669046/

相关文章:

c - 将 unsigned long 转换为字符串的缓冲区大小

c - 每次输入后刷新标准输入 - 哪种方法没有错误?

c++ - 允许调试器 Hook 外部启动的应用程序实例?

windows - 如何使用 Windows 批处理脚本将空 ASCII 字符 (nul) 写入文件?

Linux套接字和多线程程序

c++ - 为什么对固定时间步长的游戏循环使用积分? (Gaffer 谈游戏)

c - 在c代码的非阻塞设计中选择

windows - 通过 Powershell 或 Batch 将文件从 Windows 转换为 UNIX

ios - API 线程问题 iOS

java - 从另一个线程 javafx 更新 ImageView