OS X libstdc++ предотвратява прекъсвания на boost::thread?

Разгледайте следния примерен код, който създава нишка и я прекъсва от основната нишка с помощта на thread::interrupt извикване:

#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/ref.hpp>

int main()
{
    boost::thread t([]{
        int counter = 0;

        while (1){
            std::cout << "interruption enabled " << boost::this_thread::interruption_enabled() << std::endl;
            try {
                counter++;

                if (counter % 5 == 0)
                    throw std::runtime_error("runtime error!");

                std::cout << "thread function\n";
                boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
            }
            catch (boost::thread_interrupted &interruption)
            {
                std::cout << "oops!.. time to finish!" << std::endl;
                return;
                //std::cout << "...but couldn't o_O..." << std::endl;
            }
            catch (std::exception &e)
            {
                std::cout << "some exception: " << e.what() << std::endl;
            }
        }
    });

    boost::this_thread::sleep_for(boost::chrono::milliseconds(3000));
    t.interrupt();
    std::cout << "joinable: " << t.joinable() << std::endl;
    if (t.joinable())
        if (!t.try_join_for(boost::chrono::milliseconds(500)))
        {
            std::cout <<"still RUNNING\n detach it..." << std::endl;
            t.detach();
        }

    std::cout << "main thread\n";
    boost::this_thread::sleep_for(boost::chrono::milliseconds(500));

    return 0;
}

Сега, когато се компилира на OS X 10.10.3 по този начин (libc++ се използва по подразбиране):

g++ main.cpp -I<path_to_boost_1_54_0> -std=gnu++11 -lboost_thread-mt -lboost_system-mt -lboost_chrono-mt -L<path_to_boost_1_54_0>/stage/lib

изходът показва, че прекъсванията са разрешени:

interruption enabled 1
thread function
interruption enabled 1
thread function
...

Ако обаче някой ще използва libstdc++:

g++ main.cpp -I<path_to_boost_1_54_0> -std=gnu++11 -stdlib=libstdc++ -lboost_thread-mt -lboost_system-mt -lboost_chrono-mt -L<path_to_boost_1_54_0>/stage/lib

Получавам изхода, който ми казва, че прекъсването е деактивирано:

interruption enabled 0
thread function
interruption enabled 0
thread function
...

Има ли причина за такова поведение? Използвах boost v1.54.0 и този LLVM v6.1.0:

$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix

Благодаря


person peetonn    schedule 17.06.2015    source източник
comment
Не бих изключил това (точките на прекъсвания играят доста сложно със стандартните функции на библиотеката/ОС). Все пак си струва да се подаде в Boost Trac   -  person sehe    schedule 17.06.2015


Отговори (1)


Възпроизвеждах това на linux:

  • с gcc 4.8, 4.9 работи
  • с clang 3.5 и libstdc++ работи

    interruption enabled 1
    thread function
    interruption enabled 1
    thread function
    interruption enabled 1
    thread function
    interruption enabled 1
    thread function
    interruption enabled 1
    some exception: runtime error!
    interruption enabled 1
    thread function
    interruption enabled 1
    thread function
    interruption enabled 1
    thread function
    interruption enabled 1
    thread function
    interruption enabled 1
    some exception: runtime error!
    interruption enabled 1
    thread function
    interruption enabled 1
    thread function
    joinable: 1
    oops!.. time to finish!
    main thread
    
  • с clang 3.5 и libc++ не работи:

    interruption enabled 128
    thread function
    oops!.. time to finish!
    joinable: 1
    Segmentation fault (core dumped)
    

Според мен този проблем трябва да бъде докладван в списъка за усилване.

Има шанс разработчиците на boost да посочат, че това е грешка в libc++

person sehe    schedule 17.06.2015
comment
Определено подайте грешка срещу boost. - person Marshall Clow; 19.06.2015