Если у меня есть код Pthread в Linux, есть ли преимущество для реализации того же кода в std::thread?

Я занимаюсь небольшим университетским проектом, в котором я применяю различные многопоточные подходы к алгоритмам сопоставления с образцом (pthread, omp) и сравниваю их с соответствующими последовательными реализациями.

На данный момент это работает хорошо, и в зависимости от алгоритма и оптимизации gcc, я получаю более короткое время выполнения примерно в 2 - 3 раза.

Теперь я хотел бы сделать это также с использованием std::thread, однако, исходя из того, что мне удалось собрать, они реализованы с использованием Pthreads в Linux, поэтому мне было интересно, есть ли в этом смысл.

3 ответа

Решение

std::thread это функция, предоставляемая стандартным языком ISO C++, поэтому она будет доступна на платформах и реализациях, которые соответствуют C++ 11, pthreads, с другой стороны, соответствует стандарту IEEE и поэтому не является частью стандарта C++.

Так что, если ваше приложение или многопоточный код должен работать на разных платформах, имеет смысл использовать std::thread так что он просто работает на всех платформах без каких-либо изменений. если вы не беспокоитесь о кроссплатформенной совместимости, то вы просто в порядке с pthreads.

Это зависит. Вы можете сделать то же самое с обоими API, но:

  • Pthreads являются частью POSIX и, как таковые, доступны практически во всех *nix ОС, но не (изначально) в Windows.
  • pthreads - это API C: вы можете легко вызвать его из кода C, но он не использует возможности C++, чтобы сделать API приятнее / безопаснее в использовании
  • std::thread является стандартным C++ API. Он не является частью отдельной спецификации вне языка (например, pthreads является частью POSIX, а не C или C++). Таким образом, он доступен на любой платформе с современным компилятором C++ (включая *nix и Windows).
  • std::thread является C++ API, поэтому вы не можете вызывать его из C ---, но с другой стороны, его проще и безопаснее использовать. Он интенсивно использует RAII, чтобы гарантировать, что ресурсы очищаются, когда они выходят из области видимости, и позволяет создавать поток из функционального объекта со всей гибкостью, которая вам дает, вместо того, чтобы ограничиваться свободной функцией в стиле C,

Так что это зависит. Если вы хотите, чтобы ваш код использовался как из C, так и из C++, вы можете придерживаться pthreads. С другой стороны, если это только C++, и вы хотите, чтобы он работал независимо от ОС, то std::thread предпочтительнее И если вы просто хотите написать хороший код C++, std::thread это тоже путь

В дополнение к ответу Alok Save относительно переносимости (что само по себе является большим преимуществом)...

pthreads является C API, так как он не предоставляет никакой оболочки RAII, что делает его более сложным в использовании и более подверженным ошибкам, особенно в том, что касается безопасности исключений (если вы не написали свои собственные оболочки, которые вы теперь должны отлаживать и поддерживать).

std::thread и др. предоставляют хорошо проверенные, безопасные для исключения, современные оболочки C++, а также ряд удобств (например, поддержку лямбд, std::function, std::bind...), которые делают его намного проще и безопаснее в использовании. Например, этот код было бы гораздо более болезненным для написания и отладки pthreads:

std::mutex m;

struct ThreadClass {
    ThreadClass(int p1, int p2, int p3)
        : t(std::bind(&ThreadClass::run, this, p1, p2, p3))
    // notice how I'm binding to a member function, not a static one
    // additionally I'm also binding additional parameters, which
    // avoids using member variables
    {}
    void run(int p1, int p2, int p3) {
        {
            auto l = std::lock_guard<std::mutex>(m);
            // do something while locked
            // the lock will be automatically released when you
            // exit the scope, no matter how (including return and throw)
        }
        // continue unlocked
    }
    std::thread t;
}

void fireAndForget(int param) {
    std::thread t([=]() {
            // do something with param (captured by the lambda)
        });
    t.detach();
}
Другие вопросы по тегам