Обмен информацией между потоками с помощью мьютекса и сообщений

0

Изменение: мой вопрос по-прежнему остается без ответа, если кто-то захочет сделать снимок

В моем приложении MFC C++ я обмениваюсь информацией между потоком графического интерфейса пользователя и рабочим потоком, как показано в следующем коде. Я создал структуру, называемую inParams, на которую нужно ссылаться как из основного потока, так и из рабочего потока. Следовательно, я объявляю его члены типа std :: atomic, а в случаях, когда атомные типы не существуют, например. для float я использую выделенный мьютекс. В главной теме выполняется операция Foo с этой информацией, а рабочий поток - панель операций. Foo и Bar работают одновременно, и оба могут видеть изменения param1 и param2, поскольку они обновляются пользователем.

struct inParams{
    std::atomic_int param1;
    std::atomic_size_t param2;
    std::vector<customType> giantData;
    std::mutex giantDataMutex;
};

void myController::DoMainTask(){
    // Keep Handling GUI Events in this thread (main thread)
    // Create a Worker thread to do another task, I'll call it Bar
    SpawnWorkerThread()
}
void myController::SpawnWorkerThread(){
    std::thread t(&myController::tfunc, this);
    t.detach();
}
void myController::OnTimer(){  // say every 50 ms, just to simulate concurrency
    // When user changes param1 or param2, the changes affect here also
    Foo(inParams.param1, inParams.param2/* .. params list .. */);
}
void myController::tfunc(){
    while(1){
        // When user changes param1 or param2, the changes affect here also
        Bar(inParams.param1, inParams.param2, /* .. params list .. */); // 
    }
}

void myController::OnEventParam1(){ // User changed param1 in GUI
    inParams.param1 = GetValue( param1EditBox ); // GetValue gets value from Edit Box
}
void myController::OnEventParams2(){ // User changed param2 in GUI
    inParams.param2 = GetValue( param2EditBox );
}

Мой вопрос в том, является ли это AntiPattern? Должен ли я использовать сообщения вместо этого, чтобы делиться этой информацией, а не делиться параметрами с помощью мьютекса (делая их атомарными)?

C++ 11 std :: threads разрешают обмен сообщениями или я должен полагаться на PostThreadMessage API из WinAPI?

  • 1
    Если вам не нужно время отклика на микросекундном уровне, привязка ЦП для опроса атомик на предмет изменений, вероятно, излишняя. Я бы использовал condition_variable переменную, чтобы уведомить фоновый поток, чтобы он проснулся и посмотрел на измененные значения. Кроме того, detach является почти анти-паттерном. Повсеместно лучше держаться за std::thread и иметь какой-то протокол завершения работы. (т.е. вам, вероятно, нужно остановить поток, когда MyController будет уничтожен)
  • 0
    @Casey «Всегда лучше держаться за поток std :: и иметь какой-то протокол отключения» - нет, просто нет.
Теги:
multithreading
c++11
mfc
concurrency

1 ответ

0

Вы используете опрос/таймер для опроса общих переменных. Преимущество использования сообщений (PostMessage и PostThreadMessage) заключается в том, что он исключает опрос и позволяет потокам управляться событиями. Неважно, передаете ли вы данные в сообщении или используете ли вы синхронизированный доступ. В любом случае это хорошо, но опрос - это плохо.

  • 0
    На самом деле, я использую таймер только для одновременной работы Foo и Bar. В моем коде я фактически использую PostMessage для этого. Обработчики событий находятся в классе документа, и я делаю PostMessage для класса View. Меня больше беспокоит то, что, поскольку член inParams в GiantData совместно используется двумя потоками, это приведет к потере эффективности или спагетти-кода. Я назвал его гигантом, потому что он размером в несколько сотен мегабайт.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню