Многопоточность и глобальные экземпляры классов?

0

Я использую mutlithreading "первый раз" для сетевого приложения, мой вопрос - две связанные части. Если я представляю, например, кучу сообщений в udp с классами (каждое сообщение класса), было бы хорошей практикой сделать примеры такие классы глобальны, чтобы отправлять их в разных потоках, или лучший подход заключается в использовании структуры, содержащей экземпляр класса, и всю информацию о сокетах в качестве ссылки внутри этой структуры (затем используйте Pthread_create)

Я считаю, что в первом варианте необходимо проявлять большую осторожность, чтобы избежать одновременного доступа к данным (используйте pthread_mutex)

пожалуйста, предложите, как бы вы подходили к этой проблеме.

Я действительно был бы признателен за помощь

большое спасибо

  • 0
    Вам не нужно использовать потоки для сетевого программирования. Используйте select() или эквивалент вашей платформы. Или libev .
  • 0
    Если вы идете по пути c ++ 11 или c11, и ваш компилятор поддерживает потоки, вы должны использовать это вместо pthreads.
Показать ещё 3 комментария
Теги:
multithreading
sockets
pthreads

1 ответ

0

Если я правильно понял ваш вопрос, вы планируете иметь поток прослушивателя, который принимает сообщения и отправляет их нескольким потокам, которые обрабатывают это сообщение.

Здесь можно было бы использовать общую очередь:

  • Listner push() сообщения, которые он получает в очереди:
  • Рабочие потоки, если очередь не empty(), принимают следующий элемент для обработки (front()''and pop() ')
  • Конечно, очередь должна блокироваться при чтении или записи элементов с помощью мьютекса, если только вы не используете реализацию очереди без lokc.

Только очередь должна быть разделена. Вы можете сделать это с помощью глобального определения. Но с другой стороны, это хорошая практика, чтобы избежать глобальных переменных/объектов, когда вы можете. Таким образом, вам лучше создать экземпляр очереди динамически, когда вы создаете и запускаете свои потоки и передаете ссылку на очередь на каждую из них.

С стандартными потоками С++ 11 это выглядело бы примерно так:

    ... 
    std::queue<my_message_class> work_to_do;       // create queue
    std::thread t1(listener, std::ref(work_to_do));   // launch listener
    int n = max(2, std::thread::hardware_concurrency()-1);   // maximize concurency for the hardware
    std::vector<std::thread> workers;
    for (int i = 0; i < n; i++) {
        v.push_back(std::thread{ worker_function, std::ref(work_to_do) });
    }
    ...  // do something else and wait until it finishes
    t1.join();  // wait until listner finishes 
    for (auto& x :  workers) { // wait until all the worker threads finish. 
        x.join();
    }
    ...

где void listener(std::queue<my_message_class>& q) и void worker(std::queue<my_message_class>& q) будут выполнять функции.

Конечно, вы могли бы делать похожие вещи с pthreads. Но стандарты имеют то преимущество, что они независимы от платформы.

Ещё вопросы

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