Ich habe eine Funktion für gelegentlich ein Frame von GigE-Kamera, und will es schnell zurück. Das Standardverfahren ist wie folgt:Std :: Mutex mit RAII, aber fertig und im Hintergrund Thread
// ...
camera.StartCapture();
Image img=camera.GetNextFrame();
camera.StopCapture(); // <-- takes a few secs
return img;
Return Daten bereit sind nach GetNextFrame()
und StopCapture()
ist ziemlich langsam; Daher möchte ich so schnell wie möglich img
zurückgeben und einen Hintergrund-Thread spawnen, um StopCapture()
zu tun. In dem (unwahrscheinlichen) Fall, dass die Akquisition erneut gestartet wird, möchte ich den Zugriff durch einen Mutex schützen. Es gibt Orte, an denen Ausnahmen ausgelöst werden können. Daher entscheide ich mich für eine RAII-Stil-Sperre, die beim Verlassen des Bereichs freigegeben wird. Gleichzeitig muss ich die Sperre in den Hintergrund Thread übertragen. So etwas wie dieser (Pseudo-Code):
class CamIface{
std::mutex mutex;
CameraHw camera;
public:
Image acquire(){
std::unique_lock<std::mutex> lock(mutex); // waits for cleanup after the previous call to finish
camera.StartCapture();
Image img=camera.GetNextFrame();
std::thread bg([&]{
camera.StopCapture(); // takes a long time
lock.release(); // release the lock here, somehow
});
bg.detach();
return img;
// do not destroy&release lock here, do it in the bg thread
};
};
Wie kann ich das Schloss vom Anrufer mit dem Hintergrund-Thread hervorgebracht? Oder gibt es einen besseren Weg, damit umzugehen?
EDIT: Ausreichende Lebensdauer von CamIface
Instanz ist sichergestellt, bitte nehmen Sie an, es existiert für immer.
Ich würde den Thread an "CamIface" anhängen, anstatt es zu lösen. – Jarod42
http://StackOverflow.com/a/20669290/104774 sollte Ihre Frage beantworten, obwohl ich die Antwort von @PeterT – stefaanv
Ich denke nicht, es ist so einfach wie ein Move Capture. std :: mutex :: unlock muss für denselben Thread aufgerufen werden, für den der Mutex gesperrt war: http://en.cppreference.com/w/cpp/thread/mutex/unlock –