My question is, how is such a thing implemented when wanting to check for multiple events such as game events
The event loop ("main loop", "game loop") runs on a single thread. In games, most runtime processing is done on every update (so, it happens very fast in order to maintain a decent framerate). More rarely, things are spread out over multiple frames, and in some cases, certain types of processing happen only every other or third frame (e.g., if game designers feel that AI doesn't need to do updates as often as the renderer, they may deliberately reduce the rate of AI updates).
If some computation is too expensive to be performed in this way, it is done offline, if possible . I.e., most of it is precomputed/baked in some way - and the results are stored as data, and used at runtime in a simpler computation (and there's often some kind of approximation involved - to get something that's good enough, rather then strictly accurate).
Under the hood, the events are pulled from some sort of an event queue. These are typically things like user input, which come in asynchronously (essentially, under the hood, even though the CPU runs in a single thread, there's other hardware (peripherals) that runs independently (in parallel) and communicates with the CPU on the OS level). So multiple events are just entries in the queue, and as the loop "spins", when the time comes for the next update, the game just removes these events from the queue and then does something with them. This is not unique to games - this is how window systems work.
Actual games may add a level of abstraction on top of that. When it comes to pushing and handling those events, things may be arranged in a different way. For example, instead of you pulling events, you may derive from some class and override some method that will get called when some event happens. In this case, these are probably some higher level events (like "Timer Expired", "Player Triggered [TriggerName]"). Under the hood, there's still the game loop, but what's different is, before the next update, the game would do some processing to figure out what has actually happened in terms of these higher-level events, and then it would call the appropriate functions (event handlers). If there are several events, they are executed sequentially, but you don't notice because it all happens many times per second. Depending on how things are arranged, you may also be able to push your own custom events to be handled on the next update; but mostly you are just manipulating the data structures that represent the state of the game.
See this for more info.
That said, sometimes you need to perform a long-running computation (in games or in other kinds of applications) that would block the main thread and make the application unresponsive; in that case you do it on a separate thread. (E.g., you could be dynamically loading data from the disk.) However, there's a cost to threading; in a "normal" application, you can spin up a bunch of threads, but in an interactive/game-y application, it's just not feasible to spawn threads all the time as that cost quickly accumulates.
So, with games, you have to be rather deliberate about the use of threads. Since modern CPUs are multicore, games can make use of that to do certain kinds of processing in parallel and gain a certain amount of speed-up (as multiple cores mean that a couple of threads of execution can run truly simultaneously). But that's not done to process individual events, but rather to do bulk processing of data that can be processed independently in some way. Unless I'm mistaken, this is usually done to achieve something "fancy" (e.g., some kind of specialized geometry processing, specialized physics, simulations, etc.) and is by no means something all games do.
BTW, that's all on the CPU; most games, of course, assume/require a GPU, and a GPU is essentially a massively parallel data processor. Besides for rendering, it can be used by games for other kinds of computations due to programmable shaders.