Skip to content
Advertisement

How to trigger a function once a condition is met

What is an efficient way that I can trigger some function once the length of a list changes by a certain amount?

I have a nested list to which I add data 100 times per second, and I want to trigger a function once the length of the list increased by some value. I tried doing this with an if statement inside a while loop (see my_loop() below). This works, but this seemingly simple operation takes up 100% of one of my CPU cores. It seems to me that constantly querying the size of the list is the limiting factor of the script (adding data to the list in the while loop is not resource-intensive).

Here is what I have tried so far:

JavaScript

Example output:

JavaScript

Advertisement

Answer

It’s not very safe to access a list from two threads, so I’ll suggest a safer way to communicate between threads. In CPython, your code won’t corrupt the contents of the list, but you might not get exactly 200 items each time you process a batch. If you started removing items from the list in my_loop(), you could run into trouble. If you use other versions of Python without the GIL, you could have more trouble.

Before that, though, here’s the smallest change I can think of to solve the problem you asked about: CPU usage. I just added a sleep to my_loop() and cleaned up the buffer calculations so it now reports a mostly steady 201, 401, 601. Occasionally, I see a 1002.

JavaScript

Now, to do this safely, I suggest you use a queue. That will allow many threads to read or write to the queue, and it will handle the communication. If a thread tries to read from an empty queue, it just blocks until some other thread adds an item to the queue.

I wasn’t sure exactly what you wanted to do with the items, so I just put them in a list and left them there. However, now that the list is only being accessed by one thread, it’s safe to clear it out after each batch of 100 items are processed.

Because the my_loop() is now blocking, it won’t necessarily notice when you set the kill signal. Instead, I used a sentry value of None in the request queue to tell it to shut down. If that doesn’t work for you, you can use a timeout when getting an item from the queue, check the kill signal, and then try getting an item again.

JavaScript
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement