Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The right way to limit maximum number of threads running at once?

I'd like to create a program that runs multiple light threads, but limits itself to a constant, predefined number of concurrent running tasks, like this (but with no risk of race condition):

import threading  def f(arg):     global running     running += 1     print("Spawned a thread. running=%s, arg=%s" % (running, arg))     for i in range(100000):         pass     running -= 1     print("Done")  running = 0 while True:     if running < 8:         arg = get_task()         threading.Thread(target=f, args=[arg]).start() 

What's the safest/fastest way to implement this?

like image 276
d33tah Avatar asked Oct 14 '13 21:10

d33tah


People also ask

What is the maximum number of threads in Python?

Generally, Python only uses one thread to execute the set of written statements. This means that in python only one thread will be executed at a time.

What are the maximum recommended threads on a single system?

pid_max value of 131072 above means the kernel can execute a maximum of 131,072 processes simultaneously.

What happens with too many threads?

First, partitioning a fixed amount of work among too many threads gives each thread too little work that the overhead of starting and terminating threads swamps the useful work. Second, having too many threads running incurs overhead from the way they share finite hardware resources.

What is the maximum thread?

The maximum threads setting specifies the maximum number of simultaneous transactions that the Web Server can handle. The default value is greater of 128 or the number of processors in the system. Changes to this value can be used to throttle the server, minimizing latencies for the transactions that are performed.


2 Answers

It sounds like you want to implement the producer/consumer pattern with eight workers. Python has a Queue class for this purpose, and it is thread-safe.

Each worker should call get() on the queue to retrieve a task. This call will block if no tasks are available, causing the worker to go idle until one becomes available. Then the worker should execute the task and finally call task_done() on the queue.

You would put tasks in the queue by calling put() on the queue.

From the main thread, you can call join() on the queue to wait until all pending tasks have been completed.

This approach has the benefit that you are not creating and destroying threads, which is expensive. The worker threads will run continuously, but will be asleep when no tasks are in the queue, using zero CPU time.

(The linked documentation page has an example of this very pattern.)

like image 185
cdhowie Avatar answered Oct 05 '22 23:10

cdhowie


semaphore is a variable or abstract data type that is used to control access to a common resource by multiple processes in a concurrent system such as a multiprogramming operating system; this can help you here.

threadLimiter = threading.BoundedSemaphore(maximumNumberOfThreads)  class MyThread(threading.Thread):      def run(self):         threadLimiter.acquire()         try:             self.Executemycode()         finally:             threadLimiter.release()      def Executemycode(self):         print(" Hello World!")          # <your code here> 

This way you can easily limit the number of threads that will be executed concurrently during the program execution. Variable, 'maximumNumberOfThreads' can be used to define an upper limit on the maximum value of threads.

credits

like image 31
Hammad Haleem Avatar answered Oct 06 '22 01:10

Hammad Haleem