I tried creating a simple game using the pygame module in python. It's a two player game, so it involves getting simultaneous inputs or in other words, events, in the same pygame screen. I tried using multithreading, that is, by running two threads that share a pygame screen, but it didn't work due to the GIL. So, when I tried using multiprocessing instead, I faced a problem in that I couldn't share the same pygame screen. So is there a way to create a pool that has the pygame screen, like there is for sequences? If not, is there any other, perhaps better method to approach my problem? Any answers will be appreciated. Thank you.
You likely don't need either multi-threading and much less multi-processing there.
What do you mean by "it didn't work due to the GIL"? Did you get any error message when trying to do multi-threaded?
It is possible to create a naive multi-threading design that could facilitate updating objects controlled by different players, but some care would have to be taken anyway. The GIL should only impact you that you really would have no benefit like using more than 1 core in your application, but won't give you any errors.
As for using multi-processing, the secondary process would not be able to use the screen Surface anyway, and passing surfaces (images) across process is mostly not worth it (if it is feasible at all).
I meant that when I pressed a button, only one of the threads detected
key down. I did not get any errors. It is due to GIL right? I'm sorry
if I'm wrong.
No - this does not have to do with the GIL in any way -- it has to do with the pygame event API not having being designed to work with threads.
There are two ways of dealing with key-presses in Pygame: either checking for KEYDOWN events, or calling pygame.key.get_pressed. I usually prefer the second due to it not depending on key auto-repeating settings at the OS or BIOS level (unless, of course, it is an action that is to be executed just once, and not while a key is pressed).
Anyway, in any pygame related project, you should check for pygame events (key presses included) in a single place in your code, and on the same thread. Once you have the information you need from the "outside world", you can set your internal variables as you want.
But, since you don't offer any code, the most direct fix I can suggest to your multi-threaded code is to use get_pressed instead of checking for events: it will likely work from both threads. (the multi-processing code would be much more complicated than that).
Related
I have written a monitoring program for the control system at our plant. It is basically a GUI which lets the operator see the current status of the lock of the closed loop system and aware the operator in case the lock/loop breaks.
Now, the operation is heavily dependent on the responses of the GUI. My seniors told me that they prefer just the console prints instead of using TKinter based GUI as TKinter has lags while working in real time.
Can anyone please comment on this aspect?
Can this lag be checked and corrected?
Thanks in advance.
I would say that if your program is simply accessing data and not interacting with the data, then a GUI seems to be a bit of overkill. GUI's are guided user interfaces, as you know, and are made for guiding a user through an interface. If the interface is just a status, as you indicated, then I see nothing wrong with a console program.
If, however, your program also interacts with data in a way that would be difficult without a GUI, then the GUI is likely the right choice.
Have you considered a GUI in another programming language? Python is known to be a bit slow, even in console. In my experience, C++ is faster in terms of viewing data. Best of luck!
Python / tkinter in general
In a tkinter program, your code falls in one of four categories;
Initialization code that runs before the mainloop is started.
Callbacks that are run from within the mainloop.
Code running in other threads.
Code running in different processes.
In the first case, the time the code takes only influences the startup time, which for a long-running program is probably not all that relevant.
Concerning the second case, well-written callbacks should not take that long to run. In the order of tens of milliseconds, maybe up to 100 ms. If they take longer, they will render the GUI unresponsive. So unless you notice a sluggish GUI (without threads; see below) this should not be a problem.
One pitfall here are after callbacks, that is functions that will be scheduled to run after a certain time. If you launch them too often, this will also starve the GUI of time.
Another possible problem might be the manipulation of a Canvas with lots and lots of items in it.
As of Python 3.x, tkinter is thread-safe to the best of my understanding. However, in the reference implementation of Python, only one thread at a time can be executing Python bytecode. So doing heavy calculations in a second thread would slow down the GUI.
If you GUI uses multiprocessing to run calculations in another process, that should not influence the speed of your GUI much, unless you do things wrong when communicating with that other process.
Your monitoring program
What is too slow depends on the situation. In general Python is not considered a language suitable for hard real-time programs. To do hard real-time one also needs a suitable operating system.
So the question then becomes what is the acceptable lag in your system specification? Without knowing that it is impossible to precisely answer your question.
It seems that your GUI is just displaying some system status. That should not cause too much of a load, provided that you don't read/check the data too often. As described in the callbacks paragraph above it is possible to starve your GUI of CPU cycles with callbacks that run too often. From what you've written, I gather that the GUI's task is just to inform the human operator.
That leads me to believe that the task is not hugely time critical; a system that requires millisecond intervention time should not rely on a human operator.
So based on your information I would say that a competently written GUI should probably not be too slow.
I'm building a multiplayer card game with Python, gevent and django-socketio and I'm wondering about the best way to maintain state on things, bearing in mind that there'll be multiple clients connecting at once and doing things.
I'm using Redis as a datastore for the in game bits, with light object models on top (Redisco at the mo).
I'm concerned about defending against race conditions and therefore keeping the game state safe and consistent with so many clients trying to do things at once. I'm thinking that my main options are:
(1) - Ensure that all operations are safe with more that one client doing things at once (eg, a player can only interact with certain properties of their own player model, and there's some objective game state via another thread or something which does anything else.)
(2) - Use a queue with some global lock to ensure client operations all happen in a certain guaranteed order, and one finishes before the next one starts.
I'm using Python, Django, django-socketio, gevent, but think this applies more broadly.
Is this the "threadsafe" thing that people refer to?
I guess in theory I think I prefer the idea of (1), and I think that I can ensure safe operations by just modifying a single Redis key at a time, or safe sets of atomic operations, but I guess I'd either need to throw away the Redisco models or be very careful about understanding when things get saved and written. I think that's fine for just a couple of us working on things but might be dangerous longer term with more people in the codebase.
Thanks!
You have described your options well enough. Probably you need to combine both approaches.
Ensure that you have as little shared state as possible.
Use queue for modifications to whatever shared state remains.
I want to use SQLite for my GUI Python application but I have to update database every 500 MS without effecting the performance of my program.
I'm using PyQt4,So I thought about using QThread but it seems difficult to deal with, so I wondered if it was the best way before really trying to understand it.
My Question is: is QThread the best way or there are other ways?
According to the fact that python implementation rely on the GIL, even with using threads or timer you won't be able to do something (potentially costly) in your program without effecting the global performance of the program.
I will suggest you to have a look to multiprocessing module to get around of this limitation. Using this module, you will no more use threads (that are affected by the GIL), but processes (not affected by GIL).
Maybe you could create a subprocess that will arm a timer to make the update every 500ms when the main process will continue his job.
Then, you will let the system do the job of balancing the programs and it may be better in term of responsiveness (especially in a multi core environment)
I am trying to write a game that does stuff in the background until you hit a key, so it's waiting for input while doing other stuff at the same time. I have never done something like this before but I hear the solution has to do with event handling. I am trying to use either the "asyncore" library or the "signal" library (Python), but I don't understand the documentation and I think I'm missing basic concepts. Can you explain to me how I might go about using signal handling? (Or maybe there's something else I can do?)
Thanks!
Python's asyncore library is for network communication, and the signal library is used for timers and operating system signals (not related to keyboard input).
To get started, you should find a Python game programming library that suits your purposes.
If you want to do something as seemingly simple as keyboard input without help from a game programming library, you'll quickly be forced to use native APIs like Win32 and X11. By using a game programming library, you'll have get a chance to learn about events and background tasks first.
If you want to write a game in python with an SDL support, you should consider using pygame.
SDL: Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. [ http://www.libsdl.org/ ]
Pygame is python bindings with SDL: http://www.pygame.org
But if you really want to do it the hard way, I think that you should consider using the multiprocessing package.
The reason is that your game should have a main loop which is used for analysing the inputs (mouse, keyboard) and update the screen of your game. This process should not have too much overhead or the game will show signs of poor performance...
The second process should be the worker process that you want to use to code your other stuff in the background...
the multiprocessing package gives you plenty of choices for the interprocess communications (Pipe, Queue, Event)... http://docs.python.org/library/multiprocessing.html
To conclude, even if you use a framework or not for your game, your background stuff should be on a different process that your game's main loop. (Threading in python is good only for high use of I/O, so it's not the package you want right now).
I am working on a text-based game in Python 3.1 that would use timing as it's major source of game play. In order to do this effectively (rather than check the time every mainloop, my current method, which can be inaccurate, and slow if multiple people are playing the game at once) I was thinking about using the Threading.Timer class. Is it a bad thing to have multiple timers going at the same time? if so, how many timers is recommended?
For example, the user inputs to start the game. every second after the game starts it decides whether or not something happens, so there's a Timer(1) for every user playing at the same time. If something happens, the player has a certain time to react to it, so a timer must be set for that. If the user reacts quickly enough, that timer needs to end and it will set a new timer depending on what's going to happen next, etc
I think its a bad idea to use Timers in your case.
Using the delayed threads in python will result in more complex code, less accuracy, and quite possible worse performance. Basically, the rule is that if you think you need threads, you don't. Very few programs benefit from the use of threads.
I don't know what you are doing for input. You make reference to multiple players and I'm not sure whether thats on a single keyboard or perhaps networked. Regardless, your current strategy of a main loop may well be the best strategy. Although without seeing how your main loop operates its hard to say for certain.
It should be perfectly safe to have multiple timers going at the same time. Beware that it may not give much of a performance boost, as the CPython interpreter (the standard Python interpreter) uses a GIL (Global Interpreter Lock) which makes threading stuff a bit.... slow.