画像ロード中に同じ画像がロードされるのを防ぐマルチスレッドの処理の作り方が知りたい

質問内容

提示コードの///部ですが、マルチスレッドの非同期処理で複数のスレッドが同じ画像をロードする際に、一つだけロードして残りのスレッドはロードしたものを使いまわすという処理で処理時間を高速化したいのですがそれを行うにはどういったコードを書けばいいのでしょうか?

知りたいこと

一つだけロードして残りのスレッドはロードしたものを使いまわすという処理を作る方法が知りたい

現状

画像処理をそもそもブロックしてしまう形で、マルチスレッドの意味がありません

試したこと

ミュータックスを使って処理をブロックするというやり方が一番近いと思うのですが提示コードでは画像のロード処理そもそもをブロックしてしまうのでこれでは非同期の意味がありません。

環境

言語: c++
ライブラリ: SDL_Image

提示コード

cpp

1#include <Context.hpp>2#include <vector>3#include <future>4#include <iostream>5#include <glm/glm.hpp>6#include <thread>7#include <mutex>8 9struct Sprite10{11 SDL_Surface* handle;12 std::string path;13};14 15 16std::vector<Sprite> sprites;17 18std::mutex loadMutex;19//////////////////////////////////////////////////////////////////////////////////////////////////////20Sprite LoadSprite(const char* filePath)21{22 23 //std::lock_guard<std::mutex> lock(loadMutex);24 25 26 for(const Sprite& s : sprites)27 {28 if(s.path == std::string(filePath))29 {30 std::cout<<"found sprite"<<std::endl;31 return s;32 }33 }34 35 36 std::cout<<"new sprite"<<std::endl;37 SDL_Surface* image = IMG_Load(filePath);38 sprites.push_back(Sprite{image,std::string(filePath)});39 40 return sprites.back();41 42}43//////////////////////////////////////////////////////////////////////////////////////////////////////44 45class Component46{47public:48 49 Component()50 {51 52 }53 54 virtual void (*PreLoad())()55 {56 return []() -> void57 {58 std::cout<<"component"<<std::endl;59 };60 }61 62};63 64 65class PlayerControl : public Component66{67public:68 PlayerControl(): Component()69 {70 71 }72 73 virtual void (*PreLoad())() override 74 {75 return []() ->void 76 {77 78 std::this_thread::sleep_for(std::chrono::seconds(1));79 Sprite sp = LoadSprite("tile01.jpg");80 std::cout<<"PlayerControl"<<std::endl;81 82 };83 }84};85 86class EnemyControl : public Component87{88public:89 EnemyControl(): Component()90 {91 92 }93 94 virtual void (*PreLoad())() override 95 {96 return []() ->void 97 {98 std::this_thread::sleep_for(std::chrono::seconds(1));99 Sprite sp = LoadSprite("tile01.jpg")100 std::cout<<"EnemyControl"<<std::endl;101 102 };103 }104};105 106 107 108int main()109{110 Engine::Context::Init("Game",glm::ivec2(860,480)); 111 112 std::vector<std::future<void>> futures;113 114 PlayerControl player;115 EnemyControl enemy;116 117 futures.push_back(std::async(std::launch::async,enemy.PreLoad()));118 futures.push_back(std::async(std::launch::async,player.PreLoad()));119 120 for(std::future<void>& f : futures)121 {122 f.wait();123 }124 125 126 Engine::Context::Finalize();127 return 0;128}

コメントを投稿

0 コメント