Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling scheduling priority of python threads?

I've written a script that uses two thread pools of ten threads each to pull in data from an API. The thread pool implements this code on ActiveState. Each thread pool is monitoring a Redis database via PubSub for new entries. When a new entry is published, python passes the data to a function that uses python's Subprocess.POpen to execute a PHP shell to do the actual work of calling the API.

This system of launching PHP shells is necessary for functionality with my PHP web app, so launching PHP shells with Python can't be avoided.

This script will only be running on Linux servers.

How do I control the niceness (scheduling priority) of the application's threads?

Edit:

It seems controlling scheduling priority for individual threads in Python isn't possible. Is there a python solution, or at the very least a UNIX command I can run along with my script, to control the priority?

Edit 2:

Well I didn't end up finding a python way to handle it. I'm just running my script with nice now like this:

nice -n 19 python MyScript.py 
like image 428
backus Avatar asked Jul 10 '12 20:07

backus


People also ask

How do you set a priority for a thread in Python?

The python threading-docs mention explicitly that there is no support for setting thread-priorities: The design of this module is loosely based on Java's threading model. However, where Java makes locks and condition variables basic behavior of every object, they are separate objects in Python.

How do I set priority in threads?

It can be changed using the method setPriority() of class Thread. There are three static variables for thread priority in Java i.e. MIN_PRIORITY, MAX_PRIORITY and NORM_PRIORITY. The values of these variables are 1, 10 and 5 respectively.

Can we change priority of main thread?

Yes, we can change the priority of a main thread. First, get the reference of main thread using CurrentThread() method. Then call setPriority() method on it. The priority of a main thread, if explicitly not set, is always 5 i.e NORM_PRIORITY.

What are thread scheduling priorities?

Threads are scheduled to run based on their scheduling priority. Each thread is assigned a scheduling priority. The priority levels range from zero (lowest priority) to 31 (highest priority). Only the zero-page thread can have a priority of zero.


2 Answers

I believe that threading priority is not controllable in python due to how they are implemented using a global interpreter lock (GIL). Having said that, even if you could give one thread more CPU processing priority, the python implementation that hands around the GIL would not be aware of this as it handed around the GIL. If you were able to increase niceness in a single thread in your pool (say it is doing a more important job) you would need to use your own implementation of locks to give the higher priority thread access to the GIL more often.

A google search returns this article which I believe is similar to what you are asking

Explains why it doesnt work http://www.velocityreviews.com/forums/t329441-threading-priority.html

Explains the workaround I was suggesting http://bytes.com/topic/python/answers/645966-setting-thread-priorities

like image 175
Paul Seeb Avatar answered Sep 30 '22 09:09

Paul Seeb


It doesn't work, but I tried:

  1. getting the parent pid and priority
  2. launching threads using concurrent.futures.ThreadPoolExecutor
  3. using ctypes to get the (linux) thread id from within the thread(works)
  4. using the tid with os.setpriority(os.PRIO_PROCESS,tid,parent_priority+1)
  5. calling pool.shutdown() from the parent.

Even with liberal sprinkling of os.sched_yield(), the child threads never actually run past the setpriority().

Reading man pages, it seems threads don't have the capability to change (even their) scheduling priority; you have to do something with "capabilities" to give the thread the "CAP_SYS_NICE" capability. Running the process with root permissions didn't help either; child threads still don't run.

like image 31
Andrew Wagner Avatar answered Sep 30 '22 11:09

Andrew Wagner