According to the pygame.event documentation, this function gets all the events from the queue.
get events from the queue
get(eventtype=None) -> Eventlist
get(eventtype=None, pump=True) -> Eventlist
This will get all the messages and remove them from the queue.
According to the pygame.fastevent documentation, this function gets all the events from the queue.
get all events from the queue
get() -> list of Events
This will get all the messages and remove them from the queue.
So what's the difference?
I think the difference is about multithreading: event "should be called from the main thread" and fastevent is used in "multithread environments" - but I don't see any difference (in this case for example)
The idea behind fastevent was to remove some limitation in SDL's event handling code to be able to process more than 12,700 events per second.
You can still find the original documentation here and here. A few quotes:
Digging through the SDL_WaitEvent() code is when I got my nose rubbed in the fact that SDL is designed to work on operating systems that do not support threads. SDL_WaitEvent waits for events to arrive in the queue the simplest way possible, it uses SDL_Delay() to wait for 10 milliseconds and then checks to see if there are any events waiting. Checking the queue 100 times per second and possibly polling tor input events 100 times per second is great for single threaded games and it gives you the same results whether you OS supports threads or not.
...
To figure out how fast the test should run I looked at the SDL event code and saw that the queue can hold at most 127 items and since SDL_WaitEvent() looks at the queue 100 times per second we know that SDL_WaitEvent() can not remove more than (127 * 100) = 12,700 events/second and you can't push more than 12,700 events into the queue in a second.
...
Because I would like to use the same library for both the client and the server I wanted to see if I could make this code run a little faster.
...
The next step was to write my own version of SDL_WaitEvent() and use a semaphore and a condition variable to control access to the event queue. A semaphore is a simple mutual exclusion operator also known as a mutex. A mutex is used by threads to keep more that one thread from touching a variable or running a section of code at the same time. Having more than one thread changing the same data at the same time leads to horrible bugs that are hard to find. In this case I needed a mutex to keep the contents of the queue consistent. A condition variable is just a way for one thread to let other threads know that something has happened. One or more threads can wait on a condition, and when another thread signals that the condition has occurred the waiting threads wake up an go about their business.
...
When I tested that code I found that it got the SDL events and it was able to push over 30,000 events per second from my event pushing thread to the main SDL thread. I believe that the speed I'm seeing is only limited by the speed of my test machine, and not by anything in my code or in SDL. ...
Note that this does not remove the limition that the event handling functions must be
called from the main SDL thread. But it allows you to post events safely from other threads.
Related
I am creating a multi-threaded program, in which I want only 1 thread at a time to go in the critical section where is creates a socket and send some data and all the other to wait for that variable to clear.
I tried threading.Events but later realized that on set() it will notify all the threads waiting. While I only wanted to notify one.
Tried locks(acquire and release). It suited my scenario well but I got to know that lock contention for a long time is expensive. After acquiring the lock my thread was performing many functions and hence resulted in holding the lock for long.
Now I tried threading.conditions. Just wanted to know if acquiring and holding the condition for a long time, is it not a good practice as it also uses locks.
Can anyone suggest a better approach to my problem statement.
I would use an additional thread dedicated to sending. Use a Queue where the other threads put their Send-Data. The socket-thread gets items from the queue in a loop and sends them one after the other.
As long as the queue is empty, .get blocks and the send-thread sleeps.
The "producer" threads have no waiting time at all, they just put their data in the queue and continue.
There is no concern about possible deadlock conditions.
To stop the send-thread, put some special item (e.g. None) in the queue.
To enable returning of values, put a tuple (send_data, return_queue) in the send-queue. when a result is ready, return it by putting it in the return_queue.
I have some python code I'm writing that's interfacing real-world hardware. It's replacing a hardware PLC. What I'm planning is when an event trigger happens to kick off multiple threads to effect certain 'on' actions, then go to sleep for a set interval, and then perform the corresponding 'off' actions. For example: at trigger, spawn a thread that turns the room lights on. Then go to sleep for 20 minutes. Then turn the lights off and terminate the thread.
However, I will have situations where the event trigger re-occurs. In that scenario I want the entire sequence to start over. My original plan was to use threads with unique names, so if a trigger occurs, check if the 'lights' thread exists, if if does kill it, and then re-spawn a new 'lights' thread. But in researching around these parts, it seems like people are suggesting that killing a thread is a Very Bad Thing to do.
So what would a better approach be to handling my situation? Note that in my example I only talked about one thread- but in reality there will be many different threads controlling many different devices.
This is python 3.x on a Rapberry Pi running raspbian, using rpi.gpio to monitor my input triggers and an I2C relay board for my output devices in case any of that info is useful.
Thanks!
the reason for not killing off threads is that it's easy to do it in a way that doesn't give the code any chance to "clean up" appropriately. i.e. finally blocks not run, resources leaked, etc…
there are various ways to get around this, you could wait on an Event as suggested by #Jérôme, treating a timeout as a signal to carry on
asyncio is another alternative as Cancelled exceptions tend to get used to clean up nicely and don't have the problems associated with killing native threads
I have a Python object that is updated regularly, from an asynchronous I/O callback. A few threads need to wait for this object to be updated.
This "update" event is an instantaneous event, and as well the action of telling the waiting threads to wake up should be an atomic one.
I have looked for a few solutions:
Condition objects need you to acquire a lock first, which is a no-go: I need several threads to reach the wait unhindered, without fighting to acquire a lock.
Event objects generate a race condition: if a thread reaches the wait before the event is cleared, it won't wait, and on the contrary the event could be cleared before any thread is awoken.
The best solution would be an equivalent of the POSIX pause/kill combo, but for threads (at least the best that I can think of).
So, questions:
Does the pause/kill combo have an equivalent for Python 2.7 threads, and which one?
If not, what is the best compromise (in terms of reliability) for my use case, using the Python 2.7 standard library?
Here is something similar to what I would like to achieve:
# Would be a derived of threading.Event
# and the perfect solution for me, if it existed
ev = InstantEvent()
def update(*args):
# do stuff with args
ev.notifyAll()
if __name__ == "__main__":
# do startup stuff
ev.wait()
# do more stuff
each event can wait on Event object with wait() as you see. Even more: they can check periodically the event (wait with timeout) and then to do own job in the loop. Callback will set event when it done. You can combine several events by checking one then another, etc. I can not understand your problem. If you want exclusive reaction on event - use semaphore instead of event: to allow only one thread/listener to process callback completion. See more about Python threading: https://docs.python.org/3/library/threading.html
I am trying wait for any of multiple multiprocessing events at the same time, so I came up with code like this:
if e1.wait(timeout) or e2.wait(timeout):
# this part will be reached if either of both
# events is set or the wait timed out
It works like the comment says. But how does this work? Is the if polling bot methods all the time? Or is it called as soon as one event gets set?
Bonus question: Is there some clever way to adjust the code to wait for any number of events, i.e. a list of events? if True in [e1.wait(timeout),e2.wait(timeout)] does not work as expected.
It only waits for the first one. This is due to python's support of short circuiting.
Wait on a thread or process is blocking, so it will block the current thread for going future until the timeout or the thread has finished. The semantics of if in Python is short circuit, which means that if the first one returns true, then the second one will not be called - simonzack said.
Waiting on a number of threads would be kinda hard to implement and maintain for a variety of threads. I would suggest you to use Message passing, and get each process to send a message to a Queue when it is finished. This way you could just check if the queue was of ´len(n)´, where ´n´ is the number of threads/processes. see more here Queues in multiprocessing
I am fairly new to Python programming and Threads isn't my area of expertise. I have a problem for which i would hope that people here can help me out with.
Task: as a part of my master thesis, i need to make a mixed reality game which involves multiplayer capability. in my game design, each player can set a bunch of traps, each of which is active for a specific time period e.g. 30 secs. In order to maintain a consistent game state across all the players, all the time check needs to be done on the server side, which is implemented in Python.
I decided to start a python thread, everytime a new trap is laid by a player and run a timer on the thread. All this part is fine, but the real problem arises when i need to notify the main thread that the time is up for this particular trap, so that i can communicate the same to the client (android device).
i tried creating a queue and inserting information into the queue when the task is done, but i cant do a queue.join() since it will put the main thread on hold till the task is done and this is not what i need nor is it ideal in my case, since the main thread is constantly communicating with the client and if it is halted, then all the communication with the players will come to a standstill.
I need the secondary thread, which is running a timer, to tell the main thread, as soon as the time runs out that the time has run out and send the ID of the trap, so that i can pass this information to the android client to remove it. How can i achieve this ??
Any other suggestions on how this task can be achieved without starting a gazillion threads, are also welcome.. :) :)
Thanks in advance for the help..
Cheers
i have finally found a nice little task scheduler written in python, which actually is quite light and quite handy to schedule events for a later time or date with a callback mechanism, which allows the child thread to pass-back a value to the main thread notifying the main thread of its status and whether the job was successfully done or not.
people out there, who need a similar functionality as the one in the question and dont want to haggle around with threads can use this scheduler to schedule their events and get a callback when the event is done
here is the link to APScheduler
It may be easier to have the timers all done in the main thread - have a list of timers that you keep appending new ones to. Each timer doesn't actually do anything, it just has a time when it goes off - which is easier if you work in arbitrary 'rounds' than in real time, but still doable. Each interval, the mainloop should check all of them, and see if it is time (or past time) for them to expire - if it is, remove them from the list (of course, be careful about removing items from a list you're iterating over - it mightn't do what you expect).
If you have a lot of timers, and by profiling you find out that running through all of them every interval is costing you too much time, a simple optimisation would be to keep them in a heapq - this will keep them sorted for you, so you know after the first one that hasn't expired yet that none of the rest have either. Something like:
while True:
if not q:
break
timer = heapq.heappop(q)
if timer.expiry <= currenttime:
# trigger events
else:
heapq.heappush(q)
break
This does still cost you one unnecessary pop/push pair, but its hard to see how you would do better - again, doing something like:
for timer in q:
if timer.expiry <= currenttime:
heapq.heappop(timer)
# trigger events
else:
break
Can have subtle bugs because list iterators (functions in heapq work on sequences and use side effects, rather than there being a full-fledged heapq class for some reason) work by keeping track of what index they're up to - so if you remove the current element, you push everything after it one index to the left and end up skipping the next one.
The only important thing is that currenttime is consistently updated each interval in the main loop (or, if your heart is set on having it in real time, based on the system clock), and timer.expiry is measured in the same units - if you have a concept of 'rounds', and a trap lasts six rounds, when it is placed you would do heapq.heappush(q, Timer(expiry=currenttime+6).
If you do want to do it the multithreaded way, your way of having a producer/consumer queue for cleanup will work - you just need to not use Queue.join(). Instead, as the timer in a thread runs out, it calls q.put(), and then dies. The mainloop would use q.get(False), which will avoid blocking, or else q.get(True, 0.1) which will block for at most 0.1 seconds - the timeout can be any positive number; tune it carefully for the best tradeoff between blocking long enough that clients notice and having events go off late because they only just missed being in the queue on time.
The main thread creates a queue and a bunch of worker threads that are
pulling tasks from the queue. As long as the queue is empty all worker
threads block and do nothing. When a task is put into the queue a random
worker thread acquires the task, does it job and sleeps as soon as its
ready. That way you can reuse a thread over and over again without
creating a new worker threads.
When you need to stop the threads you put a kill object into the queue
that tells the thread to shut down instead of blocking on the queue.