How to programmatically run a command with a low I / O priority and high value for OS X

Is there a way to basically call system() , but with a predefined symmetry value (20) and low I / O priority from Objective-C?

(The low I / O priority level I'm talking about is launchd )

I am trying to run /usr/bin/purge from my Objective-C program.

It is also ideal for approving a method for the Mac App Store.

+6
source share
2 answers

Edit : Fork and exec no longer work, since OSX cannot really fork correctly. 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); 

It can be anywhere, in the sending unit, if you want, or anywhere in the application. No fork in sight. Also, feel free to replace system with NSTask if you want to stay ObjCish.


How about the old old fork n exec :

 #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 go through this:

  • fork : Nothing is visible here.
  • setiopolicy_np : This is the place where we set the priority of the I / O (e.g. launchd). Here are the arguments:

    • IOPOL_TYPE_DISK : We want to limit the disk I / O. In any case, there is no other way.
    • IOPOL_SCOPE_PROCESS : affects the whole process
    • IOPOL_THROTTLE : This is the policy itself. When purchasing Apple documentation , he points out this:

    Inputs / outputs with the THROTTLE policy are called THROTTLE I / O. If the I / O THROTTLE 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 stream that THROTTLE I / O issues so NORMAL I / O can use most of the I / O bandwidth. In addition, a NORMAL I / O request can bypass a previously issued THROTTLE I / O request in the kernel or driver queue and should be sent to the device first. In some cases, very large THROTTLE I / O requests will be broken down into smaller requests, which are then issued in series.

I / O priority is inherited, and the nice part sets a good value.

+4
source

An easy way to do this would be to use the taskpolicy (8) tool with the -b option:

 system("/usr/sbin/taskpolicy -b /usr/bin/purge"); 

With the -b option, taskpolicy uses setpriority (2) to set the background priority (PRIO_DARWIN_BG)

Setting the process for PRIO_DARWIN_BG has this effect on himself and all his children:

"When a thread or process is in the background, the scheduling priority is set to the lowest value, the IO disk is equal (with the behavior similar to using setiopolicy_np (3) to set the throttle policy), and the IO network is throttled for any sockets that are open after switching to the background state "All previously opened ets sockets are unaffected."

0
source

Source: https://habr.com/ru/post/948600/


All Articles