2017-03-10 13 views
13

Starałem się boost :: :: włókna barierę i nie mogę dowiedzieć się, dlaczego następujące zakleszczenia kod:Dlaczego mój kod doładowania włókno deadlocking

#include <boost/fiber/all.hpp> 
#include <iostream> 
#include <boost/range/algorithm/generate.hpp> 
#include <boost/range/algorithm/for_each.hpp> 

void barrier_test() 
{ 
    boost::fibers::barrier barrier(2); 
    std::vector<boost::fibers::fiber> myfibers(4); 
    boost::generate(myfibers, [&barrier]() { 
     return boost::fibers::fiber([](boost::fibers::barrier& barrier) { 
      static unsigned id_inc = 0; 
      const auto id = ++id_inc; 
      std::cout << "fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl; 
      barrier.wait(); 
      std::cout << "barrier passed, fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl; 
     }, std::ref(barrier)); 
    }); 

    std::cout << "main fiber: " << boost::this_fiber::get_id() << std::endl; 
    boost::for_each(myfibers, [](boost::fibers::fiber& aFiber) { 
      aFiber.join(); 
    }); 
    std::cout << "end of program" << std::endl; 
} 

Jeżeli ustawić uruchomienie jako „wysyłki” go może przejść. A więc ma coś z kolejnością biegania, ale nie wiem, co jest nie tak. Tak więc próbowałem sobie wyobrazić, jak blokowanie idzie za sceną, co działa, itp., Ale po prostu nie mogę się dowiedzieć, dlaczego oryginalny kod nie może się skończyć.

Jeśli ktoś nie chce go wypróbować, pozwól mi położyć tutaj wyjście widzę:

main fiber: 000000000042C960 
fiber id: 000000000042C6E0 - local id: 1 
fiber id: 000000000044CF60 - local id: 2 
barrier passed, fiber id: 000000000044CF60 - local id: 2 
fiber id: 000000000045D020 - local id: 3 
fiber id: 000000000046D0E0 - local id: 4 
barrier passed, fiber id: 000000000046D0E0 - local id: 4 
barrier passed, fiber id: 000000000045D020 - local id: 3 

mam skopiowany harmonogram niestandardowy algorytm testową kopalni w kodzie testowym i widzę, że po pewnym czasie, żadne włókno nie jest dostępne do biegania, lokalne włókno id 1 po prostu nie kontynuuje.

wersja Boost jest 1.63 z visual studio 2015 pakiet skompilowany i kompilacja jest w 64bit

Odpowiedz

1

Próbowałem program na Debianie/niestabilny z boost-1.63.0 i mogę potwierdzić problem. Po uruchomieniu programu przy użyciu valgrind zgłaszany jest dostęp do niezainicjowanej pamięci, a później także nieprawidłowe odczyty, więc domyślam się, że problem dotyczy tej konkretnej wersji doładowania.

+0

Dzięki, nie spróbowałem valgrind na tym przykładzie, dziękuję za to potwierdzenie. – newhouse

-1

zmiana

boost::fibers::barrier barrier(2); 

do

boost::fibers::barrier barrier(4); 

lub poczekać aż boost-1.64 jest zwolniony

+1

To nie jest rozwiązanie, w tym przypadku po prostu przeniosę barierę na większą liczbę i nie będzie ona utrzymywała włókien w parach, ale żadna. Napisałeś, że powinienem poczekać na boost-1.64, czy wiesz o tym w tym przypadku przez przypadek? – newhouse

+0

Jestem z @newhouse. Jeśli nie znasz logicznego powodu, aby zwiększyć liczbę barier, jest to w najlepszym wypadku odpowiedź kultywująca ładunek. Dałbym każdemu programistce z mojego zespołu bardzo surową rozmowę, gdyby mieli zaakceptować "magiczną radę" w ten sposób bez żadnej argumentacji. – sehe

2

Kod nigdy nie jest zakleszczony, ale jest kilka zmiennych do c onsider: Jestem na macu, używam boost 1.64, i mogłem inaczej skompilować boost.

boost? ./fibers 
main fiber: 0x7f877cc02bc0 
fiber id: 0x100cbce00 - local id: 1 
fiber id: 0x100ebce00 - local id: 2 
barrier passed, fiber id: 0x100ebce00 - local id: 2 
fiber id: 0x100fbce00 - local id: 3 
fiber id: 0x1010bce00 - local id: 4 
barrier passed, fiber id: 0x1010bce00 - local id: 4 
barrier passed, fiber id: 0x100cbce00 - local id: 1 
barrier passed, fiber id: 0x100fbce00 - local id: 3 
end of program 

FYI - skompilowany i pobiegł tak:

./bootstrap.sh --prefix=/Users/john/boost/boost_installation --without-libraries=python 

./b2 install cxxflags='-std=c++14' -j 6 threading=multi variant=release link=shared stage --reconfigure 

g++ -std=c++14 -I/Users/john/boost/boost_installation/include/ -L/Users/john/boost/boost_installation/lib -lboost_context -lboost_system -lboost_thread -lpthread -lboost_fiber -o fibers fibers.cpp 

DYLD_LIBRARY_PATH=/Users/john/boost/boost_installation/lib 

./fibers 

To nie może być to, co trzeba, ale ponieważ działa na mnie Nie mogę ci pomóc.