2017-02-04 3 views
3

У меня есть следующий код:Доступ к общим данным из рабочего потока

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().

Что мне не хватает? Как я могу получить доступ к этим данным из моего рабочего потока?

ответ

3

data - объект с автоматическим хранением. Как только он выходит из сферы действия, он больше недействителен. Я предполагаю, что data выходит за рамки до того, как рабочий поток получит возможность получить информацию.

Для того, чтобы решить эту проблему есть по существу 2 варианта:

  • создать объект синхронизации (например, CEvent), и имеет рабочий поток сигнал его, когда это делается чтение данных. Вызовите WaitForSingleObject в главном потоке, чтобы заблокировать выполнение до тех пор, пока это не произойдет. Это подлежит взаимоблокировкам, например. когда рабочий поток умирает.
  • Простым решением является использование динамического управления памятью. Используйте new, чтобы выделить экземпляр CWorkerData и передать адрес рабочему потоку. Затем рабочий поток может вызывать delete, когда это делается с объектом.
+0

D'oh! Забыл о продолжительности автоматического хранения. Спасибо, что вернул меня в нужное русло. Я использую 'CEvent', но мне все еще не очень удобно. Подумайте, возможно, мне стоит больше почитать об этом. –

+0

@JonathanWood: использование объекта синхронизации более активно, и оно применимо только в том случае, если рабочий поток не нуждается в информации на протяжении всей своей жизни. Код, который вы опубликовали, выглядит не так. Я бы пошел со вторым вариантом и полностью передал права собственности на данные. Рабочий поток может решить, когда пришло время убирать. – IInspectable

+0

Да, я сделал. Я скопировал какой-то код, хотя использовал 'CEvent' для обработки пользователя, отменяющего операцию. Просто казалось, что я, вероятно, пойму, что немного лучше. –