Is there a way to basically call system()
, but with a predefined niceness value (20) and low IO priority from Objective-C?
(The low IO priority setting I'm talking about is the one launchd
has)
I'm trying to launch /usr/bin/purge
from within my Objective-C program.
It would also be ideal for the method to be approved for the Mac App Store.
You can change the scheduling priority of a running process to a value lower or higher than the base scheduling priority by using the renice command from the command line. This command changes the nice value of a process.
The nice level is a unit of measure that describes the relative priority of the process. When discussing niceness levels, note that the scale is -20 (highest priority) to 19 (lowest priority), and that a process inherits its nice level from the parent (most often 0).
The nice value of a process can have a range between -20 (highest priority) to +19 (lowest priority); by default, its value is 0. If the nice value of a process is lower, it gets a higher priority, which means the CPU will execute that process more often.
The syntax is as follows: If no value is provided, nice sets a priority of 10 by default. A command or program run without nice defaults to a priority of zero. Only root can run a command or program with increased or high priority. Normal users can only run a command or program with low priority.
On Linux you can avoid this with the help of the ionice command. What Is I/O Priority? I/O is short for input/output. There are many types of I/O devices, but in this case it’s about storage devices. Each process that wants to read or write data to such a device is assigned a scheduling class and priority number (or “nice” value).
For example, instead of starting a program or command with the default priority, you can start it with a specific priority using following nice command. You can also use the third method which is a little confusing especially for negative niceness values. As we mentioned before, Linux allows dynamic priority-based scheduling.
A simple approach is to use the start command to launch each job with Low priority as follows: The /b switch causes the job to run in the current command window but with Low priority. Another solution would be:
Edit: Fork and exec no more, since OSX can't really fork
right. Single thread magic:
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
system("nice -n 20 /usr/bin/purge");
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_DEFAULT);
This can go anywhere, in a dispatch block if you want, or anywhere in your application. No fork
in sight. Also, feel free to replace system
with NSTask
if you want to stay ObjCish.
How about a good old fork
nexec
:
#include <unistd.h>
#include <sys/resource.h>
And:
if(fork()) {
/* Set IO priority */
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
/*IO priority is inherited*/
execl("nice", "-n", "20", "/usr/bin/purge");
}
Let's walk through this:
fork
: Nothing to see heresetiopolicy_np
: This is the place where we set IO priority (like launchd). Here are the arguments:
IOPOL_TYPE_DISK
: We want to limit Disk I/O. There is no other option available anyway.IOPOL_SCOPE_PROCESS
: Affects this whole processIOPOL_THROTTLE
: This is the policy itself. Accouring to the Apple documentation, it specifies this: I/Os with THROTTLE policy are called THROTTLE I/Os. If a THROTTLE I/O request occurs within a small time window (usually a fraction of a second) of another NORMAL I/O request, the thread that issues the THROTTLE I/O is forced to sleep for a certain interval. This slows down the thread that issues the THROTTLE I/O so that NORMAL I/Os can utilize most of the disk I/O bandwidth. Furthermore, a NORMAL I/O request may bypass a previously issued THROTTLE I/O request in kernel or driver queues and be sent to the device first. In some circumstances, very large THROTTLE I/O requests will be broken into smaller requests which are then issued serially.
I/O priority is inherited, and the nice
part of the command sets the nice value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With