我正在编写一个小程序来同时对图片进行操作。
想法是让程序处理命令行输入,然后在不同的线程上执行操作。例如,如果用户想要将5张图片加载到程序中,则负载将并行发生。这同样适用于操作。在加载一个图像的同时,另一个图像可能会模糊,另一个图像可能会旋转。
现在我有以下结构:
--Main.cpp
--Picture.h
--Tools.h
--Event.h
--ConcurrentQueue.h
对于每个命令(输入),我创建一个存储在队列中的事件。然后,许多工作线程检查队列并执行每个事件。
似乎发生的一个问题是同一图像上的操作可能同时发生(如果一个命令是“调整大小img1”而下一个命令是“crop img1”),我想避免这种情况(操作在相同的图像应按顺序发生。
另外,如果我创建10个工作线程,似乎每个线程只处理队列中的一个事件,而不是连续轮询(只发生10个事件)。
这是传递给线程构造函数的worker函数的简化版本:
void work(Tools *lib) {
if (lib == nullptr) {
cerr << "lib is null";
exit(1);
}
std::thread::id this_id = std::this_thread::get_id();
cout << "Work function entered by thread " << this_id << endl;
while (!finished.load()) {
Event item = event_queue.pop();
if (item.isEventA()) {
lib->lock_picture(filename);
/*
Do picture work here
*/
lib->unlock_picture(filename);
} else {
lib->lock_picture(filename);
/*
Do picture work here
*/
lib->unlock_picture(filename);
}
}
}
Tools
是管理转换的类。在Picture
我有一个互斥和两个函数
void Picture::lock() {
picture_mutex.lock();
}
void Picture::unlock() {
picture_mutex.unlock();
}
这些是从Tools
函数lock_picture
和unlock_picture
调用的。
Queue
是一个线程安全的实现。我正在使用全局变量finished
来表示线程停止工作(虽然目前似乎不起作用)。
欢迎任何有关改进的想法!
答案 0 :(得分:0)
您应该忘记queue / mutex等等并切换到asio,asio::strand类提供序列化执行,这就是您要查找的内容。
struct Picture
{
asio::strand _strand;
std::string _file_name;
Picture(asio::io_service&);
void Work1();
void Work2();
void Work3();
};
void main( bla bla bla)
{
asio::io_service io_service;
vector<Picture> Pictures(bla bla bla);
for_each(Pictures.begin(), Pictures.end, [](auto& elt){
elt._wrap.post([elt](){elt.Work1();});
elt._wrap.post([elt](){elt.Work2();});
elt._wrap.post([elt](){elt.Work3();}));
// Create a pool of threads to run all of the io_services.
std::vector<shared_ptr<thread> > threads;
for (std::size_t i = 0; i < 10; ++i)
threads.push_back( make_shared<thread>(
[&io_service]() {io_service.run(); }));
// Wait for all threads in the pool to exit.
for (std::size_t i = 0; i < threads.size(); ++i)
threads[i]->join();
}
asio以standalone或boost library提供。
享受!