Kann ich Boost -Thread+Atomic mit C ++ 20 Flag verwenden? Hatte eine Anwendung, die mit GCC 7.1 C ++ 17 Boost 1.75 funktioniert, aber beim Upgrade auf GCC 11,1 C ++ 20 habe ich im Boost -Thread einen Absturz erhalten. < /p>
Sanitizer meldet kein Problem. /p>
Das Programm verwendet Boost Condition_Variable.#include "boost/thread/thread.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/utility.hpp"
#include "boost/thread/condition_variable.hpp"
#include
#include
#include
#include
#include
#include
class Dispatcher;
class Task
{
public:
virtual void run() = 0;
virtual ~Task() {};
};
class TaskPool : boost::noncopyable
{
public:
typedef boost::shared_ptr task_ptr_type;
typedef boost::shared_ptr dispatcher_ptr_type;
typedef std::vector thread_pool_type;
typedef boost::posix_time::time_duration time_duration_type;
typedef std::size_t size_type;
TaskPool(const size_type Size);
~TaskPool();
size_type maxSize() const { return max_size_; }
size_type watermark() const { return watermark_; }
void setInactivTm(const time_duration_type& Inactivity_Time_Out);
const time_duration_type& getInactivTm() const { return inactivity_time_out_; }
void execute(const task_ptr_type& Task);
private:
typedef boost::mutex mutex_type;
typedef mutex_type::scoped_lock lock_type;
mutable mutex_type mutex_;
size_type max_size_;
thread_pool_type * thread_pool_;
time_duration_type inactivity_time_out_;
size_type watermark_;
size_type invocations_;
size_type executions_;
size_type loops_;
};
class Dispatcher : boost::noncopyable
{
public:
typedef TaskPool::task_ptr_type task_ptr_type;
typedef TaskPool::time_duration_type time_duration_type;
typedef TaskPool::size_type size_type;
Dispatcher();
~Dispatcher();
void setInactivTm(const time_duration_type& Inactivity_Time_Out);
bool waitReady(const time_duration_type& Time_Out);
void execute(const task_ptr_type& Task);
void terminate();
static time_duration_type defaultActivTm()
{
return boost::posix_time::milliseconds( 1 );
}
static time_duration_type minActivTm()
{
return boost::posix_time::milliseconds( 1 );
}
private:
typedef boost::mutex mutex_type;
typedef boost::condition_variable condition_variable_type;
typedef mutex_type::scoped_lock lock_type;
friend class Runner;
bool Queued_() const volatile;
bool NotQueued_() const volatile;
void execute_();
boost::thread thread_;
task_ptr_type task_;
mutable mutex_type mutex_;
condition_variable_type task_busy_cond_;
condition_variable_type task_available_cond_;
volatile bool is_terminated_;
time_duration_type inactivity_time_out_;
size_type invocations_;
size_type executions_;
size_type thread_created_;
size_type thread_terminated_;
};
class Runner
{
public:
explicit Runner(Dispatcher * Disp)
: disp_( Disp )
{ }
void operator()()
{
disp_->execute_();
}
private:
Dispatcher * const disp_;
};
Dispatcher::Dispatcher()
: is_terminated_( false ),
inactivity_time_out_( defaultActivTm() ),
invocations_( 0 ),
executions_( 0 ),
thread_created_( 0 ),
thread_terminated_( 0 )
{ }
Dispatcher::~Dispatcher()
{
terminate();
}
void Dispatcher::setInactivTm(const time_duration_type& Inactivity_Time_Out)
{
lock_type lock( mutex_ );
inactivity_time_out_ = Inactivity_Time_Out;
assert( inactivity_time_out_ >= minActivTm() );
}
bool Dispatcher::waitReady(const time_duration_type& Time_Out)
{
lock_type lock( mutex_ );
if ( !is_terminated_ &&
(thread_.get_id() == boost::thread::id()) )
{
return true;
}
while ( Queued_() )
{
if ( !task_busy_cond_.timed_wait(lock,
Time_Out) )
{
return false;
}
}
return !is_terminated_;
}
void Dispatcher::execute(const task_ptr_type& Task)
{
lock_type lock( mutex_ );
if ( thread_.get_id() == boost::thread::id() )
{
//std::cout = Dispatcher::minActivTm() );
for (thread_pool_type::iterator iter = thread_pool_->begin();
thread_pool_->end() != iter;
++iter)
{
dispatcher_ptr_type& p( *iter );
if ( p )
{
p->setInactivTm( inactivity_time_out_ );
}
}
}
void TaskPool::execute(const task_ptr_type& Task)
{
lock_type lock( mutex_ );
invocations_ += 1;
const time_duration_type min_iteration_timeout( boost::posix_time::microsec( 100 ) );
const time_duration_type max_iteration_timeout( boost::posix_time::microsec( 100000 ) );
time_duration_type timeout( 1 == max_size_ ? time_duration_type( boost::posix_time::pos_infin )
: time_duration_type( boost::posix_time::microsec(0) ) );
while ( 1 )
{
for (thread_pool_type::iterator iter = thread_pool_->begin();
thread_pool_->end() != iter;
++iter)
{
dispatcher_ptr_type& p( *iter );
loops_ += 1;
if ( !p )
{
//std::cout setInactivTm( inactivity_time_out_ );
watermark_ = iter - thread_pool_->begin();
}
if ( p->waitReady( timeout ) )
{
p->execute( Task );
executions_ += 1;
return;
}
}
if ( timeout != boost::posix_time::pos_infin )
{
timeout *= 2;
timeout = std::max(timeout,
min_iteration_timeout);
timeout = std::min(timeout,
max_iteration_timeout);
}
}
}
static TaskPool threadPool = 10;
class Wrapper : public Task
{
public:
Wrapper()
{
listener = new Listener;
}
virtual void run()
{
boost::this_thread::sleep( boost::posix_time::seconds(10) );
listener->run();
}
struct Listener
{
std::string s;
void run()
{
s = "Hello";
//std::cout
Thread -Crash steigern ⇐ C++
-
- Similar Topics
- Replies
- Views
- Last post