天天看点

C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语

文章目录

  • 1、Linux
    • 1.1 常用命令
      • 1.1.1 不占用终端运行和后台运行方式
      • 1.1.2 查询进程
      • 1.1.3 结束进程
      • 1.1.4 优先级命令
    • 1.2 C++ 代码示例
      • 1.2.1 代码一
      • 1.2.2 代码二
  • 2、Windows
    • 2.1 简介
    • 2.2 函数声明
    • 2.3 C++ 代码示例
      • 2.3.1 代码一
      • 2.3.2 代码二
  • 结语
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语

1、Linux

1.1 常用命令

1.1.1 不占用终端运行和后台运行方式

当在前台运行某个作业时,终端被该作业占据;可以在命令后面加上& 实现后台运行。

例如:

需要用户交互的命令不要放在后台执行,不过,作业在后台运行一样会将结果输出到屏幕上,如果放在后台运行的作业会产生大量的输出,最好使用下面的方法把它的输出重定向到某个文件中:

使用&命令后,作业被提交到后台运行,当前控制台没有被占用,但是一但把当前控制台关掉(退出帐户时),作业就会停止运行。nohup命令可以在你退出帐户之后继续运行相应的进程。nohup就是不挂起的意思。

nohup command &
nohup command > myout.file 2>&1 &
           

2>&1 是将标准出错重定向到标准输出,这里的标准输出已经重定向到了out.file文件,即将标准出错也输出到out.file文件中。最后一个&, 是让该命令在后台执行。

0 ,1,2分别代表stdin标准输入,stdout标准输出,stderr标准错误

,2与>结合代表错误重定向,而1则代表错误重定向到一个文件1,而不代表标准输出;换成2>&1,&与1结合就代表标准输出了,就变成错误重定向到标准输出。

command >out.file 2>&1 &
command>out.file是将command的输出重定向到out.file文件,即输出内容不打印到屏幕上,而是输出到out.file文件中。
           

1.1.2 查询进程

C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
# -e:等价于 ‘-A’ ,表示列出全部的进程
# -f:显示全部的列(显示全字段)
# 两者的输出结果差别不大,但展示风格不同。aux是BSD风格,-ef是System V风格。
# ps -aux
# ps -ef
ps -ef | grep 进程号
           
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
ps ax -o nice,pid,comm 
           
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语

1.1.3 结束进程

kill -9 进程号
           

1.1.4 优先级命令

Linux nice命令以更改过的优先序来执行程序,如果未指定程序,则会印出目前的排程优先序,内定的 adjustment 为 10,范围为 -20(最高优先序)到 19(最低优先序)。使用权限:所有使用者。

  • 进程优先级范围

    -20~19:数字越小,优先级越高

    对非root用户,只能将其底下的进程的nice值变大而不能变小。若想变小,得要有相应的权限。

用top或者ps命令会输出PRI/PR、NI、%ni/%nice这三种指标值,解释如下:

C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
PRI :进程优先权,代表这个进程可被执行的优先级,其值越小,优先级就越高,越早被执行
NI :进程Nice值,代表这个进程的优先值
%nice :改变过优先级的进程的占用CPU的百分比 
           
  • 开启某个进程并指定优先级
# nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [--help] [--version] [command [arg...]]
# nice [OPTION] [COMMAND [ARG]...]

nice -n 优先级数字 进程名字
nice -n 5 vim & 	#开启时指定vim的优先级为5,nice不是开启进程的命令,vim是开启进程

nice -n 3 ls # 将 ls 的优先序加3并执行
nice -n -3 ls # 将 ls 的优先序减3并执行

nice vi & #设置默认优先级,后台运行vi
nice -n 19 vi & #设置优先级为19,后台运行vi
nice -n -20 vi & #设置优先级为-20,后台运行vi

           
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
  • 改变进程优先级
# renice [-n] priority [[-p] pid ...] [[-g] pgrp ...] [[-u] user ...]

renice -n 优先级数字 进程pid
renice -n 5 15589  # 开启后改变进程的优先级;只能加pid
           
C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语

1.2 C++ 代码示例

在Linux中,进程运行的优先级分为-20~19等40个级别,其中,数值越小运行优先级越高,数值越大运行优先级越低。显而易见,优先级-20的运行优先级最高,优先级19的运行优先级最低。

函数nice是将当前进程运行的优先级增加指定值,既用当前进程运行的优先级加上指定值得到新的优先级,然后用新的优先级运行该进程。当计算出来的值小于-20,则进程将以优先级-20运行;当计算出来的值大于19,则进程将以优先级19运行。若增加正值,则表示降低进程运行优先级;若增加负值,则表示升高进程运行优先级。但只有具有超级用户权限的用户才可以以负数作为函数的参数,否则该函数将返回错误。

// 取得和设置程序进程执行优先权
#include <sys/time.h>
#include <sys/resource.h>

// getpriority()系统调用返回由which和who指定的进程的nice值。
int getpriority(int which, int who);


// setpriority()系统调用会将由 which 和 who 指定的进程的 nice 值设置为 prio。试图将 nice 值设置为一个超出允许范围的值(-20~+19)时会直接将 nice 值设置为边界值。
int setpriority(int which, int who, int prio);

//fork - create a child process
#include <unistd.h>
pid_t fork(void);
           

进程特性nice值运行进程间接地影响内核的调度算法:

每个进程都拥有一个 nice 值,其取值范围为−20(高优先级)~19(低优先级),默认值为 0

在传统的 UNIX 实现中,只有特权进程才能够赋给自己(或其他进程)一个负(高)优先级

非特权进程只能降低自己的优先级,即赋一个大于默认值 0 的nice 值。

调用nice来设置进程的优先级。nice系统调用等同于:

int  nice( int  increment)
{  
 int oldprio = getpriority( PRIO_PROCESS,  getpid());
 return setpriority(PRIO_PROCESS, getpid(), oldprio + increment);
}
           

1.2.1 代码一

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>

int main()
{
    pid_t pid;
    int stat_val;
    int prio;
    int inc = 3;
    int exit_code;

    pid = fork();
    if (0 == pid)
    {
        exit_code = 11;
        
        prio = getpriority(PRIO_PROCESS, getpid());
        printf("the child's priority is:%d\n", prio);

        nice( inc );
        prio = getpriority(PRIO_PROCESS, getpid());
        printf("after nice(%d), the child's priority is:%d\n", inc, prio);
    
        printf("child will exit with the exit code:%d\n", exit_code);
        exit(exit_code);
    }
    else if (pid < 0)
    {
        exit(0);
    }
    
    wait(&stat_val);
    if ( WIFEXITED(stat_val) )
    {
        printf("the child has exited, the  exit code is:%d\n", WEXITSTATUS(stat_val));
    }

    return 0;
}
           

1.2.2 代码二

#include <stdio.h>    /* printf */
#include <stdlib.h>   /* atoi, system, exit */
#include <errno.h>    /* errno */
#include <string.h>   /* strerror */
#include <unistd.h>   /* nice */

int main(int argc, char *argv[])
{
    int adjustment = 0;
    int ret;
    if ( argc > 1 ) {
        adjustment = atoi( argv[1] );
    }
    ret = nice( adjustment );
    printf( "nice(%d):%d/n", adjustment, ret );
    if ( -1 == ret ) {
        if ( errno == EACCES ) {
            printf( "Cannot set priority:%s./n", strerror( errno ) );
            exit(-1);
        }
    }
    system("nice");
    exit(0);
}
           

2、Windows

2.1 简介

  • 简单的说就是进程(线程)的优先级越高,那么就可以分占相对多的CPU时间片。 每个进程都有相应的优先级,优先级决定它何时运行和占用 CPU 时间。最终的优先级共分32级,是从 0 到 31 的数值,称为基本优先级别。
  • 优先级等级,这里我叫它进程优先级。因为一般来说它是在调用CreateProcess时指定的,CreateProcess中dwCreationFlags就可以指定进程的优先级。而线程创建时会继承进程的优先等级。
  • 因为线程才是CPU时间分配的最小单位,所以部分书上也叫线程优先等级。
  • 进程优先级可在任务管理器中的进程表中查看。右键相应的映像名称->设置优先级,即可查看当前的优先级。
    C++ 修改程序进程的优先级(Linux,Windows)1、Linux2、Windows结语
进程优先级priority class 标志 优先级值
idle (低) IDLE_PRIORITY_CLASS 4
Below 低于标准 BELOW_NORMAL_PRIORITY_CLASS 此值在2000以下系统不支持
normal (标准) NORMAL_PRIORITY_CLASS 9(前台)或 7(后台)
Above 高于标准 ABOVE_NORMAL_PRIORITY_CLASS 此值在2000以下系统不支持
high (高) HIGH_PRIORITY_CLASS 13
realtime (实时) REALTIME_PRIORITY_CLASS 24

2.2 函数声明

  • 相关函数如下:
CreateProcess: 创建进程时 也可以设置 进程优先级
SetPriorityClass: 设置进程优先级
GetPriorityClass: 获取进程优先级
SetProcessPriorityBoost: 设置激活或停用进程优先级提高功能
GetProcessPriorityBoost: 获取是否激活进程优先级提高功能
           

设置指定进程的优先级类。 此值与进程的每个线程的优先级值一起确定每个线程的基本优先级级别。

BOOL SetPriorityClass(
  [in] HANDLE hProcess,
  [in] DWORD  dwPriorityClass
);
           

检索指定进程的优先级类。 此值与进程的每个线程的优先级值一起来确定每个线程的基本优先级别。

DWORD GetPriorityClass(
  [in] HANDLE hProcess
);
           
  • 相关优先级代码如下:
#include <windows.h>
//SetPriorityClass(获取当前进程句柄,进程优先级);
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
           

2.3 C++ 代码示例

2.3.1 代码一

#include <windows.h>
#include <tchar.h>

int main( void )
{
   DWORD dwError, dwPriClass;

   if(!SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN))
   {
      dwError = GetLastError();
      if( ERROR_PROCESS_MODE_ALREADY_BACKGROUND == dwError)
         _tprintf(TEXT("Already in background mode\n"));
      else _tprintf(TEXT("Failed to enter background mode (%d)\n"), dwError);
      goto Cleanup;
   } 

   // Display priority class

   dwPriClass = GetPriorityClass(GetCurrentProcess());

   _tprintf(TEXT("Current priority class is 0x%x\n"), dwPriClass);

   //
   // Perform background work
   //
   ;

   if(!SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_END))
   {
      _tprintf(TEXT("Failed to end background mode (%d)\n"), GetLastError());
   }

Cleanup:
   // Clean up
   ;
return 0;
}
           

2.3.2 代码二

#include <Windows.h>
#include <stdlib.h>
 
int main(int argc, char **argv)
{
	STARTUPINFO silA;
	STARTUPINFO silB;
	PROCESS_INFORMATION pilA;
	PROCESS_INFORMATION pilB;
 
	ZeroMemory(&silA, sizeof(STARTUPINFO));
	ZeroMemory(&silB, sizeof(STARTUPINFO));
	ZeroMemory(&pilA, sizeof(PROCESS_INFORMATION));
	ZeroMemory(&pilB, sizeof(PROCESS_INFORMATION));
	silA.cb = sizeof(STARTUPINFO);
	silB.cb = sizeof(STARTUPINFO);
 
	// 创建进程
	CreateProcess(NULL, "test1.exe", NULL, NULL, FALSE, 0, NULL, NULL, &silA, &pilA);
	// 设置进程优先级
	SetPriorityClass(pilA.hProcess, IDLE_PRIORITY_CLASS);
	// 设置进程优先调整
	SetProcessPriorityBoost(pilA.hProcess, true);
 
	CreateProcess(NULL, "test2.exe", NULL, NULL, FALSE, 0, NULL, NULL, &silB, &pilB);
	SetPriorityClass(pilB.hProcess, HIGH_PRIORITY_CLASS);
 
	WaitForSingleObject(pilA.hProcess, INFINITE);
	WaitForSingleObject(pilB.hProcess, INFINITE);
	
	CloseHandle(pilA.hProcess);
	CloseHandle(pilB.hProcess);
 
	system("pause");
	return 0;
}
           

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;

╮( ̄▽ ̄)╭

如果您感觉方法或代码不咋地

//(ㄒoㄒ)//

,就在评论处留言,作者继续改进;

o_O???

如果您需要相关功能的代码定制化开发,可以留言私信作者;

(✿◡‿◡)

感谢各位大佬童鞋们的支持!

( ´ ▽´ )ノ ( ´ ▽´)っ!!!