Nice() 是用来改变线程优先级还是进程优先级?

发布于 2024-12-08 18:25:57 字数 1169 浏览 1 评论 0原文

nice 的手册页说“nice() 将 inc 添加到调用进程的nice值中。那么,我们可以使用它来更改创建的线程的nice值吗?”通过 pthread_create

编辑: 看来我们可以为每个线程设置nice值。

我编写了一个应用程序,为不同的线程设置不同的好值,并观察到“更好”的线程已被安排为较低的优先级。检查输出,我发现字符串“highpriority......”的输出频率更高。

void * thread_function1(void *arg)
{
  const pid_t tid = syscall(SYS_gettid);

  int ret = setpriority(PRIO_PROCESS, tid, -10);
  printf("tid of high priority thread %d , %d\n", tid ,getpriority(PRIO_PROCESS, tid));
  while(1)
  {
    printf("high priority ................\n");
  }
}


void * thread_function(void *arg)
{
  const pid_t tid = syscall(SYS_gettid);
  int ret = setpriority(PRIO_PROCESS, tid, 10);
  printf("tid of low priority thread %d , %d \n", tid ,getpriority(PRIO_PROCESS, tid));
  while(1)
  {
    printf("lower priority\n");
  }
}


int main()
{
  pthread_t id1;
  pthread_t id2;

  pid_t pid = getpid();
  pid_t tid = syscall(SYS_gettid);

  printf("main thread : pid = %d , tid = %d \n" , pid, tid);
  pthread_create(&id1, NULL, thread_function1,  NULL);
  pthread_create(&id2, NULL,thread_function,   NULL);

  pthread_join(id1, NULL);
  pthread_join(id2, NULL);
}

The man page for nice says "nice() adds inc to the nice value for the calling process. So, can we use it to change the nice value for a thread created by pthread_create?

EDIT:
It seems that we can set the nice value per thread.

I wrote an application, setting different nice values for different threads, and observed that the "nicer" thread has been scheduled with lower priority. Checking the output, I found that the string "high priority ................" gets outputted more frequently.

void * thread_function1(void *arg)
{
  const pid_t tid = syscall(SYS_gettid);

  int ret = setpriority(PRIO_PROCESS, tid, -10);
  printf("tid of high priority thread %d , %d\n", tid ,getpriority(PRIO_PROCESS, tid));
  while(1)
  {
    printf("high priority ................\n");
  }
}


void * thread_function(void *arg)
{
  const pid_t tid = syscall(SYS_gettid);
  int ret = setpriority(PRIO_PROCESS, tid, 10);
  printf("tid of low priority thread %d , %d \n", tid ,getpriority(PRIO_PROCESS, tid));
  while(1)
  {
    printf("lower priority\n");
  }
}


int main()
{
  pthread_t id1;
  pthread_t id2;

  pid_t pid = getpid();
  pid_t tid = syscall(SYS_gettid);

  printf("main thread : pid = %d , tid = %d \n" , pid, tid);
  pthread_create(&id1, NULL, thread_function1,  NULL);
  pthread_create(&id2, NULL,thread_function,   NULL);

  pthread_join(id1, NULL);
  pthread_join(id2, NULL);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余罪 2024-12-15 18:25:57

pthreads 手册页 说:

POSIX.1 还要求线程共享一系列其他属性
(即,这些属性是进程范围的而不是每个线程的):

[...]

  • 不错的价值(setpriority(2))

因此,理论上,“niceness”值对于进程来说是全局的并由所有线程共享,并且您不应该能够为一个或多个单独的线程设置特定的良好度。

然而,同一个手册页还说:

LinuxThread

此实现的显着特点如下:

[...]

  • 线程不共享共同的nice值。

NPTL

[...]

NPTL 仍然与 POSIX.1 存在一些不符合之处:

  • 线程不共享共同的好值。

因此,Linux 上的两种线程实现(LinuxThreads 和 NPTL)实际上都违反了 POSIX.1,您可以通过将 tid 传递给 setpriority()

The pthreads man page says:

POSIX.1 also requires that threads share a range of other attributes
(i.e., these attributes are process-wide rather than per-thread):

[...]

  • nice value (setpriority(2))

So, theoretically, the "niceness" value is global to the process and shared by all threads, and you should not be able to set a specific niceness for one or more individual threads.

However, the very same man page also says:

LinuxThreads

The notable features of this implementation are the following:

[...]

  • Threads do not share a common nice value.

NPTL

[...]

NPTL still has a few non-conformances with POSIX.1:

  • Threads do not share a common nice value.

So it turns out that both threading implementations on Linux (LinuxThreads and NPTL) actually violate POSIX.1, and you can set a specific niceness for one or more individual threads by passing a tid to setpriority() on these systems.

站稳脚跟 2024-12-15 18:25:57

根据 setpriority 的手册页,较低的好值( Nice 值在-2020 范围内)表示调度优先级较高。看起来您的程序按预期工作(nice = -10 赋予该线程更高的优先级)。

According to the man page for setpriority, a lower nice value (nice values are in the range of -20 to 20) means higher priority in scheduling. It looks like your program works as expected (nice = -10 gives this thread higher priority).

|煩躁 2024-12-15 18:25:57

我想测试更改这些值如何真正影响线程的优先级,因此我将您的代码片段修改为以下基准:

  • 在默认 SCHED_OTHER 调度策略上运行
  • 创建了 12 个低优先级线程以确保它们竞争资源 - 在具有 8 核的 Red hat 7 上。 (cat /proc/cpuinfo)
  • 修改了 thread_function() 以执行一些“数字运算工作”

当设置为边缘优先级时,您肯定可以使用 top -H 看到 高优先级线程运行频率更高,但其他线程不会出现饥饿现象。相关字段为 NITIME+

线程的 NICE 级别和时序视图

来自 顶部手册页

NI——不错的价值
任务的美好价值。负的好值意味着
更高的优先级,而正的nice值意味着更低的优先级
优先事项。该字段中的零仅表示优先级不会
在确定任务的调度能力时进行调整。

TIME——CPU时间
任务自启动以来使用的总 CPU 时间。

#include<cstdio> 
#include<pthread.h> 
#include<unistd.h> 
#include<sys/syscall.h> 
#include<sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 12
 
struct ThreadParams{
 const char* priority;
 const int niceLevel;
};

void * thread_function(void *arg)
{
  const pid_t tid = syscall(SYS_gettid);


  struct ThreadParams* params = (ThreadParams*)arg; 

  int ret = setpriority(PRIO_PROCESS, tid, params->niceLevel);
  printf("tid of %s priority thread %d , %d\n", params->priority, tid ,getpriority(PRIO_PROCESS, tid));
  long long int count = 0;
  while(1)
  {
      count++;
      if(count == 10000000000) //10^10 iterations
      {
          printf("%s priority ................\n", params->priority);
          count = 0;
      }
  }
}



int main()
{
  pthread_t tIdHigh;
  pthread_t tIdsLow[NUM_THREADS];

  pid_t pid = getpid();
  pid_t tid = syscall(SYS_gettid);

  printf("main thread : pid = %d , tid = %d \n" , pid, tid);
  
  struct ThreadParams highParams = {"High", -20};
  struct ThreadParams lowParams  = {"Low", 19};

  for(int i=0; i < NUM_THREADS ; i++)
  {
    pthread_create(&(tIdsLow[i]), NULL,thread_function,  &lowParams);
  }
  
  pthread_create(&tIdHigh, NULL, thread_function,  &highParams);
  
  for(int i=0; i < NUM_THREADS ; i++)
  {
    pthread_join(tIdsLow[i], NULL);
  }
  pthread_join(tIdHigh, NULL);
  return 0;

}

使用 g++.cpp -lpthread 编译。

运行 top -H -p $(pidof) 以启用线程模式并获取特定进程的信息

I wanted to test how changing these values really affects the thread's priority, so I modified your snippet to this benchmark:

  • Running on default SCHED_OTHER scheduling policy
  • Created 12 low priority threads to make sure they compete on resources - on Red hat 7 with 8 cores. (cat /proc/cpuinfo)
  • Modified the thread_function() to do some "number crunching work"

When setting to edge priorities you can definitely see with top -H that the high priority thread runs more often, but no starvation occurs to other threads. relevant fields are NI and TIME+

Thread's NICE level and timing view

From top man page:

NI -- Nice Value
The nice value of the task. A negative nice value means
higher priority, whereas a positive nice value means lower
priority. Zero in this field simply means priority will not
be adjusted in determining a task's dispatch-ability.

TIME -- CPU Time
Total CPU time the task has used since it started.

#include<cstdio> 
#include<pthread.h> 
#include<unistd.h> 
#include<sys/syscall.h> 
#include<sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 12
 
struct ThreadParams{
 const char* priority;
 const int niceLevel;
};

void * thread_function(void *arg)
{
  const pid_t tid = syscall(SYS_gettid);


  struct ThreadParams* params = (ThreadParams*)arg; 

  int ret = setpriority(PRIO_PROCESS, tid, params->niceLevel);
  printf("tid of %s priority thread %d , %d\n", params->priority, tid ,getpriority(PRIO_PROCESS, tid));
  long long int count = 0;
  while(1)
  {
      count++;
      if(count == 10000000000) //10^10 iterations
      {
          printf("%s priority ................\n", params->priority);
          count = 0;
      }
  }
}



int main()
{
  pthread_t tIdHigh;
  pthread_t tIdsLow[NUM_THREADS];

  pid_t pid = getpid();
  pid_t tid = syscall(SYS_gettid);

  printf("main thread : pid = %d , tid = %d \n" , pid, tid);
  
  struct ThreadParams highParams = {"High", -20};
  struct ThreadParams lowParams  = {"Low", 19};

  for(int i=0; i < NUM_THREADS ; i++)
  {
    pthread_create(&(tIdsLow[i]), NULL,thread_function,  &lowParams);
  }
  
  pthread_create(&tIdHigh, NULL, thread_function,  &highParams);
  
  for(int i=0; i < NUM_THREADS ; i++)
  {
    pthread_join(tIdsLow[i], NULL);
  }
  pthread_join(tIdHigh, NULL);
  return 0;

}

Compiled with g++ <FILE_NAME>.cpp -lpthread.

Run top -H -p $(pidof <PROCESS_NAME>) to enable Threads-mode and get information for specific process

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文