【问题标题】:Accessing shared data from a worker thread从工作线程访问共享数据
【发布时间】:2017-06-22 00:36:06
【问题描述】:

我有以下代码:

void COrganizerProgressDlg::LaunchWorkerThread()
{
    CWorkerData data;
    data.m_pWndOrganizerProgressDlg = this;
    data.m_pWndImageOrganizerDlg = m_pWndImageOrganizerDlg;
    ::AfxBeginThread(RunBackgroundWorker, &data);
}

这是我的RunBackgroundWorker() 方法,这是一个static 方法。

UINT COrganizerProgressDlg::RunBackgroundWorker(LPVOID pParam)
{
    try
    {
        // Run organizer engine
        COrganizerEngine engine(m_nNotifyMessage, (CWorkerData*)pParam);
        engine.Run();
    }
    catch (CException *e)
    {
        e->ReportError();
        e->Delete();
    }
    return 0;
}

数据被用于初始化我的工人阶级中的设置。

问题是我的data 变量在调用AfxBeginThread() 之前包含有效数据,但在RunBackgroundWorker() 中似乎包含垃圾。

我错过了什么?如何从我的工作线程访问这些数据?

【问题讨论】:

    标签: c++ multithreading mfc thread-safety


    【解决方案1】:

    data 是一个具有自动存储期限的对象。一旦超出范围,它就不再有效。我假设,data 在工作线程有机会获取信息之前就超出了范围。

    要解决这个问题,基本上有两种选择:

    • 创建一个同步对象(例如CEvent),并让工作线程在读取数据完成后发出信号。在主线程中调用WaitForSingleObject 以阻止执行,直到发生这种情况。这会出现死锁,例如当工作线程死亡时。
    • 更简单的解决方案是使用动态内存管理。使用new 分配一个CWorkerData 实例并将地址传递给工作线程。然后,工作线程可以调用delete,只要它完成了对象。

    【讨论】:

    • 天啊!忘记了这里的自动存储持续时间。谢谢你让我回到正轨。我一直在使用CEvent,但对它还不是很满意。想想也许我应该阅读更多相关内容。
    • @JonathanWood:使用同步对象更复杂,并且仅适用于工作线程在其整个生命周期中不需要信息的情况。您发布的代码看起来并非如此。我会选择第二种选择,并完全转移数据的所有权。工作线程可以决定何时清理。
    • 是的,我做到了。我复制了一些代码虽然使用CEvent 来处理用户取消操作。似乎我应该更好地理解这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 2011-08-29
    相关资源
    最近更新 更多