イメージをrawデータとしてディスクにダンプするスレッドがあります。それは数分の間うまく動作し、突然それは何かをやめるだけです。ランダムな時間の後にランダムな位置でエラーなしにスレッドが停止する
コマンドライン出力から、ループ内のランダムな位置で停止することがわかりました。
プログラムはこのスレッド内でクラッシュしません(イメージバッファがいっぱいになってスレッドが実行を停止した直後にクラッシュします)ので、エラー/例外/スレッドからの何もありません。
ここに私のコードのスケッチです:
class ImageWriter
{
public:
// constructor, destructor
void continueWriting();
private:
void writeImages();
std::thread m_WriterThread;
bool m_WriterThreadRunning;
std::mutex m_ThreadRunningMutex;
ImageManager * m_ImageManager;
};
ImageWriter::continueWriting()
{
// whenever a new image is acquired, this function is called
// so if the thread has finished, it needs to be restarted
// this function is also used for the first start of writing
m_ThreadRunningMutex.lock();
if (m_WriterThreadRunning)
{
m_ThreadRunningMutex.unlock();
}
else
{
m_ThreadRunningMutex.unlock();
if(m_WriterThread.joinable())
{
m_WriterThread.join();
}
m_WriterThreadRunning = true;
m_WriterThread = std::thread(&ImageWriter::writeImages, this);
}
}
void ImageWriter::writeImages()
{
while (true)
{
// MyImage is a struct that contains the image pointer and some metadata
std::shared_ptr<MyImage> imgPtr = m_ImageManager->getNextImage(m_uiCamId);
if(imgPtr == nullptr)
{
// this tells the ImageWriter that currently there are no further images queued
break;
}
// check whether the image is valid. If it's not, skip this image and continue with the next one
[...]
// create filename
std::stringstream cFileNameStr;
cFileNameStr << [...];
std::ofstream cRawFile(cFileNameStr.str().c_str(), std::ios::out | std::ios::binary);
unsigned char * ucDataPtr = imgPtr->cImgPtr;
if(cRawFile.is_open())
{
// calculate file size
unsigned int uiFileSize = [...];
cRawFile.write(reinterpret_cast<char*>(ucDataPtr), uiFileSize);
cRawFile.close();
}
// dump some metadata into a singleton class for logging
[...]
}
m_ThreadRunningMutex.lock();
m_WriterThreadRunning = false;
m_ThreadRunningMutex.unlock();
}
ImageManagerのは、画像取得の世話をし、取得した画像をキュークラスです。また、continueWriting()をトリガーします。イメージは取得されるよりも速く書き込まれる可能性があるため、continueWriting()メカニズムが必要です。
なぜこのスレッドはランダムな位置でランダムに実行され、エラーは発生しませんか?
Valgrindは私のコントロール内に何も結果をもたらさない。 スレッドの優先度を設定しようとしましたが、それは何の違いもありませんでした。 私も別のディスクを試しましたが、それはどちらの違いもありませんでした。
m_WriterThreadRunningを読んだり、mutexロックの下でfalseを書いても、本当に保護されていないのですか?このミューテックスは、1つのブールを保護するだけですか?代わりにアトミックを使用します。スレッドを停止/開始することはありませんが、イメージがキューにない場合はwaitのメカニズムを実装し、continueWritingは待機スレッドを停止するようにスレッドに通知します。 –
m_WriterThreadRunningの書き込みは、古いスレッドがジョイントされた後、新しいスレッドが開始される前に行われます。そのため、競合状態は発生しません。 待機メカニズムが理にかなっています。私には起こりませんでした。それが問題を解決しない場合でも、それはより読みやすいはずです、良いアイデア! –
症状:1)マルチスレッド。 2)明示的なミューテックスの使用。 3)短時間の使用後にロックする。診断:合理的な疑いを越えて、デッドロック状態にあります。 –