I have been messing around for some time with a small game and now trying to add multithreading to the equation. Sure it is not needed but I just wanted to test it out this is what I got. Problem lies with in where at game start if just freezes my computer and I have to hit the reset button. I am unsure to what I am missing or making my mistake on, but right at program start it tries to do the multithreading area of the program which it shouldn't. Even removing the calls doesn't stop it from running.
skipping most of the non needed stuff Full program link can be added if needed
Most of the multithreading was taken directly from a book I was reading a while back. Game Programming All In One pg 405-413 for those who have the book.
pthread_mutex_lock and pthread_mutex_unlock return 0 if they were successful but you treat that as an error condition. This is wrong, you don't treat it as an error condition.
Not to mention that your textprintf'ing to the screen when the mutex fails to lock defeats the purpose of using the mutex (you are using a mutex to say that it is okay to use Allegro's resources, so if the mutex locking fails, you can't use Allegro's resources).
Also, note that pthread_mutex_lock will not fail because the mutex was already locked. It will only fail if the mutex was destroyed. pthread_mutex_unlock will also only ever fail if the mutex was destroyed.
Your call to pthread_exit isn't needed, also.
Game Programming All In One pg 405-413 for those who have the book.
We hear a ton of horrible programming practices gotten from this book.
[edit]
Edited for correctness.
Nothing else to say than what CGamesPlay said. Too slow :p
Fixed a few things. But still remains that right at start the multithreaded part of the program is trying to start and just freezes. I used a graphical feature to show what was being multithreaded. At the start of the game is a main menu the "bouncing balls" should be applied when the game is started but instead they are starting at the main screen it gets (guessing) 3-5 loops and locks up. What I do not understand is what am I doing that starts the calls for the multithreaded parts of my program.
Compiles no errors just locks up on run.
Yeah, you must have a dead lock somewhere in your code. That is typically why threaded program froze.
What should I be looking for in my program. What kind of things might cause this. It really doesn't effect the game play to have it out now, but perhaps later when there is more going on I may want to have it implemented just in case.
I code in a simple form "Newbish" so to speak.
1 | if (Balls[n].y > Floors.y - BallSize) |
2 | { |
3 | spls = 0; |
4 | splashed[n].x = Balls[n].x; |
5 | splashed[n].y = Balls[n].y; |
6 | s = n; //Mark location of Splash |
7 | play_sample((SAMPLE *)data[EXPLODE2_WAV].dat, volume, pan, pitch, 0); |
8 | splashes(); |
9 | dead[n] = 1; //mark ball as dead |
10 | Balls[n].y = 0 + BallSize; |
11 | dropball(); |
12 | lives--; |
13 | FrC = FrC - 25; //Changes the floor color on dropped ball |
14 | FbC = FbC + 25; |
15 | FgC = FgC; |
16 | } |
Showing how simplistic I keep things.
Maybe I should add everything that adds multithreading until I get the error. Let me see what causes it exactly.
You should add some TRACE(...) in your code to see where you stop.
Step by step debugging could help too.
Trace is new to me should try it out. I am fairly new to the programming thing and havent done any debugging stuff with my compiler yet will have to try that aswell.
hitting the post button to test
ok with just this line commented out the program works.
circlefill(active_page,x[a],y[a],BallSize / 5,c[a]);
if I add
textprintf_ex(screen,font,0,10,makecol(255,255,255),-1,"%i",x[1]);
instead of the circle movements it shows that it works but again starts right off the bat before it should. sorry I edit a lot.
What kind of things might cause this.
A deadlock happens when two subjects cross they need for objects. Example, you have P1, P2 which are processes and R1, R2 which are resources.
P1 owns R1 and needs R2, P2 owns R2 and needs R1. You have a deadlock because none of the processes can go on until the other releases the resource it's owning.
I would suggest you skip threading entirely and then come back to it later.
If you can't do that, then I would start off with some dead simple thread programs and work your way up. This app is a tad complicated.
Taking the easy way is never my thing. I got it working and have isolated the problem. Now working around the problem is something else.
If I use...
circlefill(screen,xx[z],yy[z],BallSize / 5,c[z]);
instead of...
circlefill(active_page,xx[z],yy[z],BallSize / 5,c[z]);
So my next question is how do I tell the multithread to hold off and wait till the main program is done. I assumed that would be done with pthread_mutex_lock and pthread_mutex_unlock but I guess I am wrong.
Where would be a good place to learn about pthread?
It makes no sense whatsoever to use threads to handle paging.
I am using the thread to handle background graphics. Having some fun. The paging is done out side the thread.
show_video_bitmap(active_page); if (active_page == buffer) active_page = buffer2; else active_page = buffer; clear_to_color(active_page, makecol(0, 0, 0));
question was on how to tell the threaded area of my program to hold on while the main program uses a resource.
if I use
for (z = 1; z < 1000; z++){ circlefill(active_page,xx[z],yy[z],BallSize / 5,c[z]); }
outside the threaded program it works fine. But the point is to get it to work inside the threaded area.
Taking the easy way is never my thing. I got it working and have isolated the problem. Now working around the problem is something else.
If you're not into 'easy things' then why are you asking these guys to write your code for you instead of you studying the relevant subject ie threads and communicating process with semaphores and mutexes?
Wow tons of help. I understand as to how they work not to why it is not working.
another example which SHOULD lock variables till it is done but doesn't
1 | void* thread0(void* data) |
2 | { |
3 | int my_thread_id = *((int*)data); |
4 | //For Pixelate Demo Addition |
5 | while (lives > 0) |
6 | { |
7 | pthread_mutex_lock(&threadsafe); |
8 | for (z = 1; z < 20; z++){ |
9 | if (xx[z] > SCREEN_W - 4 - xi[z] || xx[z] < 3 - xi[z]) |
10 | xi[z] = -xi[z]; |
11 | if (yy[z] > Floors.y - 4 - yi[z] || yy[z] < 13 - yi[z]) |
12 | yi[z] = -yi[z]; |
13 | xx[z] = xx[z] + xi[z]; |
14 | yy[z] = yy[z] + yi[z]; |
15 | //trying to get the active_page to work in here |
16 | circlefill(active_page,xx[z],yy[z],BallSize / 5,c[z]); |
17 | } |
18 | pthread_mutex_unlock(&threadsafe); |
19 | rest(1); |
20 | //For Pixelate demo addition |
21 | } |
22 | //pthread_exit(NULL); |
23 | return NULL; |
but instead of helping find what seems to everyone else like a small mistake I get the run around.
The point is it's not small, multi threading is really hard. Can anyone gurantee that allegro, or direct x or anything else isn't running a thread in the background that's causing deadlocks with your thread? I can't.
I can. I use threads a lot with allegro, and all the deadlock I had were caused by me.
This also a deadlock caused by me. Simple comment out showed me what was doing it aswell.
If I just use a BITMAP that my main program does not have access to like "screen" then everything works fine. Only problem is it still slows the main program down where to my understanding each thread should have its own speed.
Yeah, but if they both access the same critical section, they will wait each other to free the locked ressource before doing some stuff.
I was also under the impression when I pthread_mutex_lock it would lock the resources it was using till pthread_mutex_unlock was passed both my main loop and my thread use this. While screen works both can not use active_page even when locking for some reason.
If I could lock out the main loop from using the BITMAP active_page when the thread was using it things would be easier and vice versa.
Locking a mutex prevents other threads from locking the same mutex. If a thread locks a mutex, and another tries to lock the same mutex, the second will block (wait) until the first thread unlocks the mutex. THis makes it so two threads can't touch the same data at the same time.
my understanding each thread should have its own speed.
When two threads handle the same data, they have to do syncronization (usually through mutexes) so they don't step on each others toes. This quickly leads to performance degradation on both parts. Using threads is not a recipe for speed. It's a tool to help make more efficient use of resources when properly handled.
Thanks to those that helped and gave advice. I was able to get my program to work. Although not entirely the way I wanted but work none the less.
To GullRaDriel for pointing out that I may have a deadlock. Once figured out where was fairly easy to fix. Thanks.
To Marco Radaelli for the explination of exactly what happens when a deadlock occurs. Thanks
To Dustin Dettmer helping to get me to realize I am over my head
To nonnus29 with that awsome link with all sorts of information about threads and much more. Thanks.
Thanks for all the help.
-Consider this thread closed.