Безопасно ли смешивать boost :: thread с C ++ 11 std :: mutex? - PullRequest
0 голосов
/ 16 февраля 2019

Безопасно ли использовать std::mutex и его родственников в программе, которая запускает свои потоки через boost?

(Использование std::thread не вариант для меня (я думаю), так как приложение нуждается вмного места в стеке, а на некоторых платформах требует переопределения размера стека по умолчанию при создании.)

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

То, как вы запускаете потоки (pthread_create, boost::thread, std::thread), ортогонально используемым примитивам синхронизации (std против boost против Intel TBB против libatomic vs и т. Д.).

В противном случае вы не сможете смешивать и сопоставлять библиотеки, использующие эти разные API, в одном приложении.

Низкоуровневые примитивы синхронизации, такие как атомарные, мьютексы и условные переменные, могут быть помещены в общую память и использоваться различными процессами без явного создания каких-либо дополнительных потоков.Кроме того, основной поток приложения создается для вас ядром ОС без использования API-интерфейсов пользовательского пространства.

0 голосов
/ 17 февраля 2019

приложению требуется много места в стеке, а на некоторых платформах требуется переопределение размера стека по умолчанию при создании

std::thread использует pthread_create для создания потоков на платформах, которые поддерживаютPOSIX.Другой вариант для вас - переопределить pthread_create, установить размер стека и вызвать исходный pthread_create.

Рабочий пример Linux (у меня нет доступа к MacOS, чтобы попробовать его там):

#include <cstdio>
#include <thread>
#include <dlfcn.h>

namespace {

size_t const STACK_SIZE = 8 * 1024 * 1024;

int pthread_create_override(pthread_t* thread, pthread_attr_t const* attr, void*(*start_routine)(void*), void* arg) noexcept {
    std::printf("%s\n", __PRETTY_FUNCTION__);

    pthread_attr_t attr2;
    if(attr)
        attr2 = *attr;
    else
        if(pthread_attr_init(&attr2))
            std::abort();

    size_t stacksize = 0;
    pthread_attr_getstacksize(&attr2, &stacksize);
    if(stacksize < STACK_SIZE) {
        if(pthread_attr_setstacksize(&attr2, STACK_SIZE))
            std::abort();
    }

    static auto const real_pthread_create = reinterpret_cast<decltype(&pthread_create)>(::dlsym(RTLD_NEXT, "pthread_create"));
    int rc = real_pthread_create(thread, &attr2, start_routine, arg);

    if(!attr)
        pthread_attr_destroy(&attr2);

    return rc;
}

} // namespace

extern "C" {

int pthread_create(pthread_t* thread, pthread_attr_t const* attr, void*(*start_routine)(void*), void* arg) {
    return pthread_create_override(thread, attr, start_routine, arg);
}

} // namespace

int main() {
    std::thread t([]() { std::printf("%s\n", __PRETTY_FUNCTION__); });
    t.join();
}

Выходы:

int {anonymous}::pthread_create_override(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)
main()::<lambda()>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...