Thread: theoretical question about c programming

  1. #1
    Registered User
    Join Date
    Dec 2013
    Posts
    241

    theoretical question about c programming

    when thinking about the concept of making games in C , I always wonder how it is done when programming threads in C is merely impossible .
    I mean, let's think about the simplest shooting game - we have the user as as one character , and we have the computer as the second character, also we have to keep all the GUI on and all of them has to work in the backend simultaneously in order to make the game playable.

    so how games like this are built in C ? how do your make your code do several things at once?

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Without threads the program simply rotates around the various tasks, performing a little of each at a time, and it does it so quickly it looks like they're all happening at the same time.

    However, threads are certainly not impossible in C. What gave you that idea?
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by oogabooga View Post
    However, threads are certainly not impossible in C.
    The first C standard to support threading was only ratified in 2011. Threading, with a pre-C11 implementation (compiler, library, etc), required use of libraries or operating system capabilities beyond the C standard - the terms "multithreading" and "C standard conformant" were mutually exclusive. Even now, not everyone has the luxury of being able to use a C11 implementation.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I just did a game where the player is chased by one or several "muggers", while he tries to recover his stolen "gold" in various rooms. The action of the player is a big loop, but basically just gets the latest keystroke from the user (if one has been pressed), and makes a few updates to the console as the player moves around. When that loop has completed several iterations, or a small amount of time (roughly a tenth of a second) has passed, then the "muggers" moving loop function is called, and the muggers all move to give chase. They don't loop until the muggers move, the loop runs until another tenth of a second has elapsed. Health points and gold numbers are updated on the screen, and then it's back to the player's loop again.

    The key is to adjust the time spent in each of these two main functions that control movement in the game, and to have all the muggers move in the same loop, even though they are in different locations in the room. I know it's not multi-threaded, but even to me, it LOOKS like it's multi-threaded (which my compiler supports quite nicely). When you press a key, the "muggers" react instantly to it (apparently).

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by grumpy View Post
    The first C standard to support threading was only ratified in 2011. Threading, with a pre-C11 implementation (compiler, library, etc), required use of libraries or operating system capabilities beyond the C standard - the terms "multithreading" and "C standard conformant" were mutually exclusive. Even now, not everyone has the luxury of being able to use a C11 implementation.
    If you're going to program any modern game, you're going to need to use plenty of libraries / operating system capabilities beyond the C standard. Threading would just be one more drop in the bucket.

    That said, to the original poster, games are much less multithreaded than you think; threading actually slows things down a lot if you're frequently manipulating the same data in multiple threads, because synchronizing access to the data adds overhead. It's only when tasks are largely working on independent data that multithreading shows its benefits.
    Last edited by Cat; 01-31-2014 at 11:09 PM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  6. #6
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Whether or not threading is used and the type of threading varies between games and the operating systems they run on. Some of my racing games use Windows threading. A common scheme uses one thread for sampling controller input, one thread for the physics (integrations, collisions, ...), one thread for the graphics, and a thread for positional updates of other cars if in online mode. There were additional threads, probably used to keep everything synchronized to a specific timing. I'm also aware of one old racing game that used a single windows thread, but similar to a previous post, used the equivalent of a round robin (non-pre-emptive) internal min-kernel to run the various tasks.

    An issue with some of the older windows threaded games is that they weren't expecting the true simultaneous processing that came about when multi-core cpu's started being used. Those games have thread interface weaknesses that causes them to lock up or crash on multi-core cpu's, and the work-around is to set the "affinity" for the game to a single cpu. (This can be done via task manager or in some cases by altering the program executable header with an old microsoft tool called imagecfg.exe).

    The point here is that different games use different schemes to implement some form of threading or a round robin loop that spends so much time with each task (and some method to control the timing precisely).
    Last edited by rcgldr; 02-01-2014 at 02:43 AM.

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by Dave11 View Post
    let's think about the simplest shooting game - we have the user as as one character , and we have the computer as the second character, also we have to keep all the GUI on and all of them has to work in the backend simultaneously in order to make the game playable.

    so how games like this are built in C ? how do your make your code do several things at once?
    Rather than threads, you can use events for this. For example, if the GUI is only updated once every 10 ms or so, that's probably enough for a smooth visual. The rest of the time can be used to perform other tasks.

    Here is one link about events vs. threads

    http://www.csd.uoc.gr/~hy527/papers/...ousterhout.pdf

    An implementation of events in C is libevent. It makes it easy to assign event handlers and it manages the event loop.

    libevent

  8. #8
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by c99tutorial View Post
    Here is one link about events vs. threads

    http://www.csd.uoc.gr/~hy527/papers/...ousterhout.pdf

    An implementation of events in C is libevent. It makes it easy to assign event handlers and it manages the event loop.
    The csd pdf file uses the term "event driven", but then describes a "round robin" type process. "event driven" normally means an application or process that responds to events as they occur, including doing preemptive context switches to higher priority threads and/or interrupts. A "round robin" architecture typically calls a series of task oriented functions one at a time in sequential order, where everything is stuck until a task returns to the kernel allowing it to call the next task in the list.

    The mentioned libevent is using a combination of interrupt/or and operating system events to call "event handlers" via call backs. During an event, the main stream code is interrupted and a context switch is made to the event handler. In some environments, the events can be nested with higher priority events interrupting lower priority events.

    Another alternative would be similar to windows main message handler, where messages are received and processed one at a time, and each message type calls a user specified message handler or the code calls the default message handler.

    One way to avoid the locking overhead issues mentioned in the csd pdf file is to use some type of generic messaging system where each thread has a primary input message queue and sleeps until one or more messages are placed on that threads message queue. Two main functions are used, one to send messages, the other to receive messages. I've seen this architecture used in computer peripherals (hard drives, backup tape drives, communication boxes, ... ) as well as games or other multi-threaded applications.
    Last edited by rcgldr; 02-01-2014 at 11:07 AM.

  9. #9
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Sounds like threadpooling, correct me if I'm wrong.

  10. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    The csd pdf file uses the term "event driven", but then describes a "round robin" type process. "event driven" normally means an application or process that responds to events as they occur, including doing preemptive context switches to higher priority threads and/or interrupts.
    O_o

    The paper does indeed describe an "event driven" model.

    You are combining aspects of "event driven" and "forking" models.

    With "event driven" models, the system/library manages resources without "blocking" until a resource is available for processing; when a resource is available for processing, the system/library hands the resource over to a specific routine which may then process the resource without "blocking" because the resource is known to be available. (Basically, "event driven" programming is about "reacting"--a resource is ready--instead of taking constant action--asking "is a resource ready".) The dispatching of resources by the resource manager does not continue until the routine processing the last event has completed. In other words, the "event driven" model is designed precisely so that threads--or "forked" processes--are not necessary to process concurrent events as the system/library resolves resource "readiness" for synchronous dispatch.

    You can, of course, combine "event driven" programming with "forking" models. (In fact, the recommendation for many "event driven" libraries comes in the form of "You should spawn a "worker" thread if processing the resource is even remotely expensive".) However, most libraries are not designed with the "forking" model in mind even though many are "thread safe" if you choose to use threads.

    The mentioned libevent is using a combination of interrupt/or and operating system events to call "event handlers" via call backs.
    Unless "libevent" has changed considerably, the implementation is inherently single-threaded under "POSIX" exactly matching the underlying behavior suggested by the relevant paper.

    The "Windows" "message pump" is another implementation of "event driven" models.

    Sounds like threadpooling, correct me if I'm wrong.
    The "way to avoid locking" seems to be describing the concept at a higher level--more general "Producer/Consumer Pattern"--than any specific implementation.

    Using a pool of threads with a "job queue" is a specific instance of that pattern.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  11. #11
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by phantomotap View Post
    Unless "libevent" has changed considerably
    No, you're correct, I missed the part of the description that mentions it replaces an event loop similar to Windows message handler loop. I thought it was using something similar to Windows asynchronous I/O or multimedia timer event call back routines, where the main thread is interrupted and the call back function is called (similar to an interrupt). Some kernels allow for nesting of call back events (similar to nested interrupts).

    A separate issue for most games is that the physics part of the game has to run at a very precise frequency, sometimes at a frequency that isn't "convenient". If the frequency happens to coincide with the tick rate or a multiple of the tick rate for a timer, then the timer can be used to create an event to wait for. If not, then it's common to have some type of function in the game that after a physics step, "waits" (in a loop) for a timer ((new_value - old_value) >= delay_value) to achieve fixed frequencies (or as close as possible) that aren't convenient multiples of a timer's rate.

    I assume that most newer games are truly threaded because they run faster on multi-core cpus (some games specify a multi-core cpu as part of their system requirements).
    Last edited by rcgldr; 02-01-2014 at 03:25 PM.

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    If not, then it's common to have some type of function in the game that after a physics step, "waits" (in a loop) for a timer ((new_value - old_value) >= delay_value) to achieve fixed frequencies (or as close as possible) that aren't convenient multiples of a timer's rate.
    O_o

    These days even "rigid body" physics are often too costly--a lot more "bodies"--to "clamp" just physics. You'll more often see rendering and physics "clamped" to force the frequency to "coincide with the tick rate".

    [Edit]
    This was more of a general complaint in seeing my "FPS" never above 25/30 in a lot of games.
    [/Edit]

    *shrug*

    Well, I guess accumulation and interpolation are more common these days what with multiple cores being common.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  13. #13
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by phantomotap View Post
    This was more of a general complaint in seeing my "FPS" never above 25/30 in a lot of games. ... Well, I guess accumulation and interpolation are more common these days what with multiple cores being common.
    For example, in the case of Need For Speed Shift, the physics engine always runs at 180 hz, which is one of those inconvenient frequencies, while the video frames per second ranges from 35 to 70 or so, depending on processor speed and graphics. Another example, the multmedia timer runs at 1024 hz, but Windows emulates a 1000 hz timer by including an extra tick on the 43rd, 96th, and 128th ticks, using 128 ticks every 125 ms to emulate a 1000 hz timer. Either 1024 or 1000hz wouldn't work out nicely for Need For Speeds physics rate of 180 hz, so after a physics step, it delays to a 180hz boundary by polling a high frequency clock counter.

  14. #14
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    For example, in the case of Need For Speed Shift, the physics engine always runs at 180 hz, which is one of those inconvenient frequencies, while the video frames per second ranges from 35 to 70 or so, depending on processor speed and graphics.
    O_o

    Really? I had remembered "Need For Speed: Shift" as "clamping" physics to rendering "FPS"; well, "clamped" to "FPS" but with multiple physics passes per frame.

    [Edit]
    Well, you are referencing an older game. I just read that and thought "Oh, really, the latest "Need for Speed" used delays?" without actually checking what the last release was called.

    I was thinking of "Need for Speed: Rivals" which, for the PC version I played, was "clamped" to 30 "FPS".
    [/Edit]

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  15. #15
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,791
    I'm more worried about the lack of graphics than threads.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 12-18-2013, 07:08 AM
  2. Theoretical question regarding text files
    By TobiasK in forum C Programming
    Replies: 9
    Last Post: 07-26-2013, 11:26 AM
  3. Please help me in this theoretical question of C++ Templates
    By umair_attock in forum C++ Programming
    Replies: 15
    Last Post: 01-22-2009, 09:28 PM
  4. not just theoretical tutorials!!
    By npokcu in forum C Programming
    Replies: 1
    Last Post: 10-21-2001, 02:43 PM
  5. theoretical problem
    By cozman in forum C++ Programming
    Replies: 8
    Last Post: 09-06-2001, 04:02 PM