Я надеюсь проверить, заблокирован ли поток с помощью библиотеки boost.thread.
Я написал следующие коды, чтобы проверить это.
worker.h
#pragma once
#include <boost/thread.hpp>
class Worker
{
private:
boost::thread *_thread;
boost::thread *_checker_thread;
boost::condition_variable _cond;
boost::mutex _mutex;
bool _run;
int _id;
public:
Worker(int id);
~Worker();
void initialize();
void start();
void join();
static unsigned process(void *param);
static unsigned check_running(void *param);
};
worker.cpp:
#include "worker.h"
#include <iostream>
#include <boost/chrono.hpp>
Worker::Worker(int id) : _thread(nullptr)
{
_id = id;
}
Worker::~Worker()
{
std::cout << "Invoked destructor()" << std::endl;
if (_thread) {
delete _thread;
_thread = nullptr;
}
}
void Worker::initialize()
{
std::cout << "Invoked initialize()" << std::endl;
boost::thread::attributes attrs;
_run = true;
try {
_thread = new boost::thread(attrs, boost::bind(Worker::process, this));
_checker_thread = new boost::thread(attrs, boost::bind(Worker::check_running, this));
} catch(...) {
std::cerr << "Begin thread error" << std::endl;
if (_thread) {
delete _thread;
_thread = nullptr;
}
if (_checker_thread) {
delete _checker_thread;
_checker_thread = nullptr;
}
}
}
void Worker::start()
{
std::cout << "Invoked start()" << std::endl;
_cond.notify_one();
}
void Worker::join()
{
std::cout << "Invoked join()" << std::endl;
if (_thread) {
_thread->join();
}
}
unsigned Worker::process(void *param)
{
std::cout << "Invoked process()" << std::endl;
Worker *worker = (Worker*)param;
boost::unique_lock<boost::mutex> lock(worker->_mutex);
while (worker->_run) {
worker->_cond.wait(lock);
std::cout << "Start process" << std::endl;
for (int i = 0; i < 20; i++) {
boost::this_thread::sleep_for(boost::chrono::milliseconds{1});
std::cout << i << std::endl;
}
worker->_run = false;
}
return 0;
}
unsigned Worker::check_running(void *param)
{
Worker *worker = (Worker*)param;
std::cout << "Start check running" << std::endl;
while (worker->_run) {
if (worker->_mutex.try_lock()) {
std::cout << '-';
worker->_mutex.unlock();
} else {
std::cout << '+';
}
boost::this_thread::sleep_for(boost::chrono::milliseconds{1});
}
return 0;
}
main.cpp:
#include "worker.h"
#include <iostream>
int main()
{
Worker worker(99);
worker.initialize();
for (int i = 0; i < 26; i++)
{
if (i == 5)
{
worker.start();
}
boost::this_thread::sleep_for(boost::chrono::milliseconds{1});
std::cout << static_cast<char>(i + 'a') << std::endl;
}
worker.join();
return 0;
}
Этот код имеет 3 темы:
- Печать алфавита от a до z в main ().
- Вывести число от 0 до 19 в Worker :: process (). Запускается после печати «е».
- Проверьте, заблокирован ли поток номера печати в Worker :: check_running (). Если он заблокирован, он печатает «+», иначе «-».
В Worker :: check_running () я использовал mutex.try_lock (), чтобы проверить, заблокирован ли поток. Но в этом случае mutex.unlock () должен быть вызван.
Как я могу сделать этот код в стиле RAII? Я имею в виду, что хочу использовать другой шаблон блокировки, такой как boost :: unique_lock <>, чтобы не пропустить mutex.unlock ().
@ Майлз Буднек,
Спасибо за ваш ответ.
Я применил ваш ответ, но он показал другой результат.
Мои коды показывают результат, как показано ниже:
Invoked initialize()
Invoked process()Start check running
-a
-b
-c
-d
-e
Invoked start()
Start process
+f
+0
g
+1
h
+2
i
...
17
x
+18
y
+19
z
Invoked join()
Invoked destructor()
Ваши коды действуют следующим образом:
Invoked initialize()
Invoked process()
Start check running
-a
-b
-c
--d
-e
Invoked start()
-f
-g
-h
...
-x
-y
-z
Invoked join()
---------------- ... -----------Start process
++0
+1
+2
+3
+4
5
+6
+7
...
+18
+19
Invoked destructor()
Не могли бы вы проверить это, пожалуйста?