2014-12-05 3 views
1

Я пытаюсь несколько простых boost::thread кода следующим образом:Повысьте :: нить вылету при простом цикле

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

void InputLoop() 
{ 
    std::cout << "Loop start" << std::endl; 

    int y = 0; 
    while (1) 
    { 
     std::cout << "y = " << y << std::endl; 
     y++; 
    } 

    std::cout << "Loop end" << std::endl; 
} 

int main() 
{ 
    std::cout << "Main start" << std::endl; 

    boost::thread t(InputLoop); 
    t.start_thread(); 

    while (1) 
    { 
     int x = 0; 
    } 

    std::cout << "Main end" << std::endl; 

    return 0; 
} 

Это дает выход:

Main start 
Loop start 
y = 0 
y = 1 
y = 2 
. 
. 
. 
The program has unexpectedly finished 

Таким образом, происходит сбой во время InputLoop(). Значение y при возникновении сбоя варьируется между различными пробегами и колеблется от примерно 0 до примерно 10000.

Что происходит?

+0

Он работает на http://coliru.stacked-crooked.com/. Хотя, без t.start_thread(); и с "warning: unused variable 'x' [-Wunused-variable] int x = 0;" – SChepurin

+1

Либо мне нужно обновить, либо понизить уровень моего повышения. Потому что 'start_thread' утверждает, что« личное »разрешение доступа на моей платформе (OSX 10.7.1) – WhozCraig

+0

@WhozCraig - Извините, отредактированный, забыл упомянуть -« /usr/local/include/boost/thread/detail/thread.hpp:177 : 14: error: 'void boost :: thread :: start_thread()' private void start_thread() ". Просто хотел указать, что он не «неожиданно неожиданно». – SChepurin

ответ

1

Вы не должны называть start_thread?

Это не требуется, так как это утечка внутренней детали реализации:

In my code I accidentally called this method and it resulted in my callback being started twice.

Таким образом, вы получите несинхронизированную доступ к std::cout, y, что приводит к Undefined Behaviour

Исправление находится в этой фиксации: https://github.com/boostorg/thread/commit/750c849b0f0dff79a289111955260a4147ac7f59

0

Даже несмотря на это публичный метод start_thread в class thread, это не в documentation. Это для reason:

Launching threads

A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. [...]

If you wish to construct an instance of boost::thread with a function or callable object that requires arguments to be supplied, this can be done by passing additional arguments to the boost::thread constructor:

Независимо от того, какой конструктор вы используете, поток уже запущен:

// <boost/thread/detail/thread.hpp> 
template < 
    class F 
> 
explicit thread(BOOST_THREAD_RV_REF(F) f 
//, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0 
): 
    thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f)))) 
{ 
    start_thread(); 
} 

Как это start_thread определено?

void start_thread() 
{ 
    if (!start_thread_noexcept()) 
    { 
    boost::throw_exception(thread_resource_error()); 
    } 
} 

start_thread_noexcept на самом деле не в заголовке, но часть libboost_thread:

// boost/lib/thread/src/thread.cpp 
bool thread::start_thread_noexcept() 
{ 
    thread_info->self=thread_info; 
    int const res = pthread_create(&thread_info->thread_handle, 0, &thread_proxy, thread_info.get()); 
    if (res != 0) 
    { 
     thread_info->self.reset(); 
     return false; 
    } 
    return true; 
} 

Вы фактически создали две темы. И это (возможно) реализация thread_proxy, которая создает ваше поведение.

 Смежные вопросы

  • Нет связанных вопросов^_^