简体   繁体   中英

Is it safe to mix boost::thread with C++11 std::mutex?

Is it safe to use std::mutex and its kin in a program that starts its threads via boost?

(Using std::thread is not an option for me (I think), as the application needs a lot of stack space, and on some platforms requires overriding the default stack size upon creation.)

是的,您可以在使用boost::thread创建的线程中使用std::mutex

the application needs a lot of stack space, and on some platforms requires overriding the default stack size upon creation

std::thread uses pthread_create to create threads on platforms that support POSIX. Another option for you is to override pthread_create , set the stack size and call the original pthread_create .

A working Linux example (I don't have access to MacOS to try it there):

#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();
}

Outputs:

int {anonymous}::pthread_create_override(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)
main()::<lambda()>

The way you start threads ( pthread_create , boost::thread , std::thread ) is orthogonal to synchronisation primitives you use ( std vs boost vs Intel TBB vs libatomic vs etc..).

Otherwise, you wouldn't be able to mix and match libraries that use these different APIs in one application.

Low-level synchronisation primitives such as atomics, mutexes and condition variables, can be placed in shared memory and used by different processes without creating any extra threads explicitly at all. As well as the main application thread is created by the OS kernel for you without using any of the user space APIs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM