gibboncho
@gibboncho

Как правильно обрабатывать изображения в стороннем потоке?

Доброго время суток, котятки! Пишу софт, который обрабатывает изображения в стороннем потоке. да да, знаю, нельзя этого делать, но нужно именно так. Наверняка кто-нибудь знает как это делать потокобезопасно. Сейчас все работает, но после нескольких итераций он подвисает и не работает дальше. Примерный код:
Так создаю поток:
DWORD id;
HANDLE thread = CreateThread(NULL, 0U, MainThread, (LPVOID)td1,THREAD_PRIORITY_NORMAL, &id);
CloseHandle(thread);

Так создаю bitmapы и тд:
Vcl::Graphics::TBitmap *bmp1 = new Vcl::Graphics::TBitmap();
	Vcl::Graphics::TBitmap *bmp2 = new Vcl::Graphics::TBitmap();
	TPngImage *png = new TPngImage();
	TJPEGImage *jpeg = new TJPEGImage();
	Rxgif::TGIFImage *gif = new Rxgif::TGIFImage();
	TPicture *pic = new TPicture();
	TPicture *picTrash = new TPicture();

Так вот работаю с ними:
bmp1->Canvas->Lock();
			bmp2->Canvas->Lock();
			bmp2->Canvas->FillRect(bmp2->Canvas->ClipRect);
			bmp2->Canvas->Draw(0,0,bmp1);
			bmp2->Canvas->Unlock();
			bmp1->Canvas->Unlock();

Главная форма во время работы дико подвисает, и проц грузит почти на 100%, но есть же программы, которые быстро и без зависов обрабатывают изображения.
  • Вопрос задан
  • 519 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Mercury13
Программист на «си с крестами» и не только
Что я пока вижу.
1. В любой высокоуровневой библиотеке CreateThread использовать ЗАПРЕЩЕНО, вместо этого используй beginthreadex (или что-то ещё, предоставленное библиотекой). Или, раз уж ты по-чёрному используешь VCL, особо не убудет, если будешь использовать TThread.
2. Lock и Unlock — это обыкновенный мьютекс. Все конкурирующие потоки, кому захочется рисовать на холсте, ждут и курят, ничего не делая.
3. Самое-то главное ты упустил. Если ждёшь помощи, не нужно так секретничать, что не поймёшь, в чём дело. Где — хотя бы примерно — тело потока, и что делается в главном потоке?
4. А как надо работать? Есть некая структура данных, в которой мы возвращаем из потока обработанные картинки, и volatile bool isWorking, который отвечает за то, работает поток или нет. Когда этот флажок false, главный поток имеет право работать с нашей структурой. Он переключается в true — в структуре может быть любой мусор, обращаться к ней запрещено! Если ещё и надо предупредить, когда поток закончился и можно забирать информацию — TThread.Synchronize или PostMessage. То и другое работает только в GUI-программах, если консольная — то через события (CreateEvent).
5. А почему «нельзя этого делать»? Если партия приказала, значит, надо. Просто многопоточность — это тяжёлое дело, ошибки на каждом шагу, но «принципиально нельзя» — нет такого.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы