Ramon
Ramon

Reputation: 434

boost fibers work_stealing barrier causes segfault

This is a completed version of an example I found somewhere in the boost docs on how to spawn worker threads to use with fibers work_stealing algo.

#include <iostream>
#include <chrono>
#include <boost/fiber/all.hpp>

int main() {
    size_t count = std::thread::hardware_concurrency();
    boost::fibers::barrier b{count};
    for(int i=0;i<count;i++) {
        new std::thread([&b, &count] {
            boost::fibers::use_scheduling_algorithm<boost::fibers::algo::work_stealing>(count);
            b.wait();
        });
    }
    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

This causes a segfault most of the time and I don't understand why.

Here the cmake file:

cmake_minimum_required(VERSION 3.12)
set(CMAKE_CXX_STANDARD 17)

set(VERSION 1_68_0)
set(BOOST_ROOT /home/User/boost_${VERSION})

find_package(Boost REQUIRED COMPONENTS fiber)
find_package(Threads)

include_directories(${Boost_INCLUDE_DIRS})
add_executable(test test.cpp)
target_link_libraries(test ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})

I am running Fedora 28 and built Boost from source with gcc 8.1.1 and didn't install it. The project is built with the same compiler. (libc++ isn't installed anywhere.) I get the same behaviour with git branches master and develop as well as 1_67_0. I feel like I'm missing something obvious here.

Upvotes: 1

Views: 498

Answers (2)

Ramon
Ramon

Reputation: 434

I've found another example which uses thread_barrier.hpp from the examples folder instead of the boost::fibers::barrier. Everything else the same it works like charm.
This means that despite the documentation stating "The fiber synchronization objects provided by this library will, by default, safely synchronize fibers running on different threads." (source) they are not in fact threadsafe. I now recognize that it is never actually stated that these are threadsafe but I still think this (combined with the example at the bottom I initially worked from) is very misleading. If you pay very close attention and assume that every single word was placed deliberately you could see through this unintentional deception.

Upvotes: 1

xlrg
xlrg

Reputation: 2109

It's a bug that will be fixed in branch develop. The problem is that the registration of the work-stealing algos at the internal container is not properly synchronized. Your example would look like:

size_t count = std::thread::hardware_concurrency();
for(size_t i=1;i<count;i++) {
    new std::thread([&count] {
        boost::fibers::use_scheduling_algorithm<boost::fibers::algo::work_stealing>(count);
    });
}
boost::fibers::use_scheduling_algorithm<boost::fibers::algo::work_stealing>(count);

Upvotes: 3

Related Questions