Hello !. I have a problem with ALLEGRO_THREAD.
I want to save a lot of bitmaps on the hard drive and I would like to be able to
do it by running several threads while containing "al_save_bitmap" but
I only get them to run one after another and not two at a time ..
If you can help me I would really appreciate it. Thank you
------------------------------------------------------------------
static void * SUB(ALLEGRO_THREAD *hilo, void *arg)
{
al_save_bitmap(ARCHIVOS[num_elem], foto_final[arg]);
return (0);
}
//*************************************************
void GUARDAR_FOTO()
{
no_hilo: if (hilo1==1 && hilo2==1) { goto no_hilo; }
if (hilo1 == 0)
{
hilo1 = 1;
hilo[0] = al_create_thread(SUB, 0);
al_start_thread(hilo[0]);
al_destroy_thread(hilo[0]);
hilo1 = 0;
return;
}
if (hilo2 == 0)
{
hilo2 = 1;
hilo[1] = al_create_thread(SUB, 1);
al_start_thread(hilo[1]);
al_destroy_thread(hilo[1]);
hilo2 = 0;
return;
}
}
//**************************************** main ********
hilo1=0;
hilo2=0;
for (num_elem=0; num_elem < 100; num_elem++)
{
GUARDAR_FOTO();
}
I can't really see how that code would work at all, but..
If it were me I would just split your list of 100 photos into two, and have one thread do the first 50 and one thread do the last 50, then use al_join_thread to wait for them to finish.
Does that help?
Hello, thanks for answering, because of the complexity of the program it is impossible for me to separate them into 2 lots, that's why I wanted to split the calls to al_save_bitmap into two execution threads. I need to call a thread to save one bitmap while the other thread goes saving another one simultaneously and when one of them finishes it receives the next bitmap.
The program works perfect, I can process more than 1200 photos of 8 mp a day,
but I need more speed, so I thought about using several processor cores through the creation of threads.
This is a serializing call. This won't work if you want to run them in parallel.
You might want to look at "Thread Pools" or "Producer-consumer queues". It should be possible to find examples using Posix pthreads which is quite close to Allegro's thread API.
First though, are sure that your processing is not bound by the time taken to write out to disk? If it is, you won't see much benefit from multithreading.
Yes, the problem is that it runs in series and not in parallel. I do not know how to do it in parallel. I think the processing time is longer than the time needed to write to the disk. My knowledge is very limited, I thought I could do in a simple way two threads in parallel that contain only the "al_save_bitmap" instruction. Could you give me some basic example of how to do it?
Have a look at:
https://gist.github.com/pedro-w/2de196b801b44f0bc77f745d0c9ea509
It's a start and hopefully others will suggest a better way to do it.
(should definitely use a condition variable rather than that unlock-sleep-lock thing but I never can remember how to use them properly)
Thanks to all, the example of the link seems the way forward. I hope to understand ...
I don't think allegro supports saving bitmaps from a thread other than the one whose display is current. I've got a working ThreadPool, and if I save the bitmaps from the spawned threads, they are black. If I save them from main, they look right.
In fact, the GDI save routines fail to acquire a lock on the bitmap to save, so no data is copied to the GDI struct which gets saved.
I don't think allegro supports saving bitmaps from a thread other than the one whose display is current. I've got a working ThreadPool, and if I save the bitmaps from the spawned threads, they are black. If I save them from main, they look right.
In fact, the GDI save routines fail to acquire a lock on the bitmap to save, so no data is copied to the GDI struct which gets saved.
Yeah, that's expected, but perhaps not well documented.
I did not know that. Is it also true for memory bitmaps? I was drawing into memory bitmaps and saving them from 2 threads, and it worked OK on macos.
On Windows, it works for memory bitmaps. I just tested it.
I've also been running some informal tests with my ThreadPool. 8 jobs versus 1 is faster by a factor of between 2 and 3 times.
This is some example code that uses my ThreadPool class that I've put together over the last few days. I will integrate it into Eagle soon, but this version is standalone (only depends on Allegro 5). API is super simple.
I'm not going to post it yet, for some reason I can't have more than exactly 853 jobs. If I add 854 jobs or more, the thread pool breaks and never finishes its work.
UPDATE :
I fixed avoided the strange thread problem and have a working implementation of a thread pool now. You can see it here :
https://www.allegro.cc/forums/thread/617504