侧边栏壁纸
博主头像
noerror

虚灵不寐,众理具而万事出。

  • 累计撰写 238 篇文章
  • 累计创建 9 个标签
  • 累计收到 2 条评论
标签搜索

目 录CONTENT

文章目录

pthread_setschedparam函数用法详解

noerror
2022-10-04 / 0 评论 / 0 点赞 / 35 阅读 / 2,038 字 / 正在检测是否收录...

pthread_setschedparam函数用法详解

pthread_setschedparam函数简介

  • 头文件包含
#include <pthread.h>
  • 函数定义
int pthread_setschedparam(pthread_t  thread , int  policy ,
                          const struct sched_param * param );
int pthread_getschedparam(pthread_t  thread , int * policy ,
                          struct sched_param * param );
  • 编译链接选项
-pthread

pthread_setschedparam函数常见使用错误

  • 链接错误
    undefined reference to `pthread_setschedparam'
    解决办法:添加链接选项
-pthread
  • 编译错误
    warning: implicit declaration of function ‘pthread_setschedparam’ [-Wimplicit-function-declaration]
    解决办法:包含头文件
#include <pthread.h>

pthread_setschedparam函数详细描述

pthread_setschedparam ()函数设置线程thread 的调度策略和参数
policy为thread 指定新的调度策略。policy 支持的值及其语义在sched (7)中描述
param指向的结构为thread 指定了新的调度参数,调度参数在以下结构中维护:

struct sched_param {
   int sched_priority;     /* Scheduling priority */
};

可以看到,只支持一个调度参数。有关每个调度策略中调度优先级的允许范围的详细信息,请参阅sched (7)
pthread_getschedparam ()函数返回policy和param 分别指向的缓冲区中线程thread 的调度策略和参数。返回的优先级值是由最近影响thread 的pthread_setschedparam ()、pthread_setschedprio (3)或pthread_create (3)调用设置的。返回的优先级不反映由于调用任何优先级继承或优先级上限函数(例如,请参见pthread_mutexattr_setprioceiling (3)和pthread_mutexattr_setprotocol (3)))而导致的任何临时优先级调整

pthread_setschedparam函数返回值

如果成功,这些函数返回0;错误时,它们返回一个非零错误号。如果pthread_setschedparam ()失败,则不更改thread的调度策略和参数。

pthread_setschedparam函数错误码

这两个函数都可能失败,并出现以下错误:

  • 找不到ID为thread的线程。

pthread_setschedparam ()可能还会失败,并出现以下错误:

  • EINVAL policy不是可识别的策略,或者param对policy 没有意义
  • EPERM 调用方没有适当的权限来设置指定的调度策略和参数。

POSIX.1还记录了pthread_setschedparam ()的 ENOTSUP (“试图将策略或调度参数设置为不受支持的值”)错误

pthread_setschedparam函数其他说明

有关更改线程调度策略和优先级所需权限及其影响的说明,以及每个调度策略中优先级的允许范围的详细信息,请参阅sched (7)

pthread_setschedparam函数使用举例

下面的程序演示了pthread_setschedparam ()和pthread_getschedparam ()的使用,以及许多其他与调度相关的pthreads函数的使用。
在接下来的运行中,主线程将其调度策略设置为SCHED_FIFO,优先级为10,并初始化一个thread attributes对象,其调度策略属性为SCHED_RR,调度优先级属性为20。然后程序使用pthread_attr_setinheritsched (3))将thread attributes对象的inherit scheduler属性设置为PTHREAD_EXPLICIT_SCHED ,这意味着使用这个attributes对象创建的线程应该从thread attributes对象获取它们的调度属性。然后程序使用thread attributes对象创建一个线程,该线程显示其调度策略和优先级。

$ \fBsu\fP      # Need privilege to set real-time scheduling policies
Password:
# \fB./a.out \-mf10 \-ar20 \-i e\fP
Scheduler settings of main thread
   policy=SCHED_FIFO, priority=10

Scheduler settings in \(aqattr\(aq
   policy=SCHED_RR, priority=20
   inheritsched is EXPLICIT

Scheduler attributes of new thread
   policy=SCHED_RR, priority=20

在上面的输出中,可以看到调度策略和优先级取自thread attributes对象中指定的值。
下一次运行与上一次运行相同,只是将inherit scheduler属性设置为PTHREAD_INHERIT_SCHED ,这意味着使用thread attributes对象创建的线程应该忽略attributes对象中指定的调度属性,而是从创建线程中获取它们的调度属性。

# \fB./a.out \-mf10 \-ar20 \-i i\fP
Scheduler settings of main thread
   policy=SCHED_FIFO, priority=10

Scheduler settings in \(aqattr\(aq
   policy=SCHED_RR, priority=20
   inheritsched is INHERIT

Scheduler attributes of new thread
   policy=SCHED_FIFO, priority=10

在上面的输出中,可以看到调度策略和优先级来自创建线程,而不是thread attributes对象。
请注意,如果我们省略了"-i\ i"选项,那么输出将是相同的,因为PTHREAD_INHERIT_SCHED是inherit scheduler属性的默认值。Program source&

/* pthreads_sched_test.c */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define handle_error_en(en, msg) \e
       do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void
usage(char *prog_name, char *msg)
{
   if (msg != NULL)
       fputs(msg, stderr);

   fprintf(stderr, "Usage: %s [options]\en", prog_name);
   fprintf(stderr, "Options are:\en");
#define fpe(msg) fprintf(stderr, "\et%s", msg);          /* Shorter */
   fpe("\-a<policy><prio> Set scheduling policy and priority in\en");
   fpe("                 thread attributes object\en");
   fpe("                 <policy> can be\en");
   fpe("                     f  SCHED_FIFO\en");
   fpe("                     r  SCHED_RR\en");
   fpe("                     o  SCHED_OTHER\en");
   fpe("\-A               Use default thread attributes object\en");
   fpe("\-i {e|i}         Set inherit scheduler attribute to\en");
   fpe("                 \(aqexplicit\(aq or \(aqinherit\(aq\en");
   fpe("\-m<policy><prio> Set scheduling policy and priority on\en");
   fpe("                 main thread before pthread_create() call\en");
   exit(EXIT_FAILURE);
}

static int
get_policy(char p, int *policy)
{
   switch (p) {
   case \(aqf\(aq: *policy = SCHED_FIFO;     return 1;
   case \(aqr\(aq: *policy = SCHED_RR;       return 1;
   case \(aqo\(aq: *policy = SCHED_OTHER;    return 1;
   default:  return 0;
   }
}

static void
display_sched_attr(int policy, struct sched_param *param)
{
   printf("    policy=%s, priority=%d\en",
           (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
           (policy == SCHED_RR)    ? "SCHED_RR" :
           (policy == SCHED_OTHER) ? "SCHED_OTHER" :
           "???",
           param\->sched_priority);
}

static void
display_thread_sched_attr(char *msg)
{
   int policy, s;
   struct sched_param param;

   s = pthread_getschedparam(pthread_self(), &policy, &param);
   if (s != 0)
       handle_error_en(s, "pthread_getschedparam");

   printf("%s\en", msg);
   display_sched_attr(policy, &param);
}

static void *
thread_start(void *arg)
{
   display_thread_sched_attr("Scheduler attributes of new thread");

   return NULL;
}

int
main(int argc, char *argv[])
{
   int s, opt, inheritsched, use_null_attrib, policy;
   pthread_t thread;
   pthread_attr_t attr;
   pthread_attr_t *attrp;
   char *attr_sched_str, *main_sched_str, *inheritsched_str;
   struct sched_param param;

   /* Process command\-line options */

   use_null_attrib = 0;
   attr_sched_str = NULL;
   main_sched_str = NULL;
   inheritsched_str = NULL;

   while ((opt = getopt(argc, argv, "a:Ai:m:")) != \-1) {
       switch (opt) {
       case \(aqa\(aq: attr_sched_str = optarg;      break;
       case \(aqA\(aq: use_null_attrib = 1;          break;
       case \(aqi\(aq: inheritsched_str = optarg;    break;
       case \(aqm\(aq: main_sched_str = optarg;      break;
       default:  usage(argv[0], "Unrecognized option\en");
       }
   }

   if (use_null_attrib &&
           (inheritsched_str != NULL || attr_sched_str != NULL))
       usage(argv[0], "Can\(aqt specify \-A with \-i or \-a\en");

   /* Optionally set scheduling attributes of main thread,
      and display the attributes */

   if (main_sched_str != NULL) {
       if (!get_policy(main_sched_str[0], &policy))
           usage(argv[0], "Bad policy for main thread (\-m)\en");
       param.sched_priority = strtol(&main_sched_str[1], NULL, 0);

       s = pthread_setschedparam(pthread_self(), policy, &param);
       if (s != 0)
           handle_error_en(s, "pthread_setschedparam");
   }

   display_thread_sched_attr("Scheduler settings of main thread");
   printf("\en");

   /* Initialize thread attributes object according to options */

   attrp = NULL;

   if (!use_null_attrib) {
       s = pthread_attr_init(&attr);
       if (s != 0)
           handle_error_en(s, "pthread_attr_init");
       attrp = &attr;
   }

   if (inheritsched_str != NULL) {
       if (inheritsched_str[0] == \(aqe\(aq)
           inheritsched = PTHREAD_EXPLICIT_SCHED;
       else if (inheritsched_str[0] == \(aqi\(aq)
           inheritsched = PTHREAD_INHERIT_SCHED;
       else
           usage(argv[0], "Value for \-i must be \(aqe\(aq or \(aqi\(aq\en");

       s = pthread_attr_setinheritsched(&attr, inheritsched);
       if (s != 0)
           handle_error_en(s, "pthread_attr_setinheritsched");
   }

   if (attr_sched_str != NULL) {
       if (!get_policy(attr_sched_str[0], &policy))
           usage(argv[0],
                   "Bad policy for \(aqattr\(aq (\-a)\en");
       param.sched_priority = strtol(&attr_sched_str[1], NULL, 0);

       s = pthread_attr_setschedpolicy(&attr, policy);
       if (s != 0)
           handle_error_en(s, "pthread_attr_setschedpolicy");
       s = pthread_attr_setschedparam(&attr, &param);
       if (s != 0)
           handle_error_en(s, "pthread_attr_setschedparam");
   }

   /* If we initialized a thread attributes object, display
      the scheduling attributes that were set in the object */

   if (attrp != NULL) {
       s = pthread_attr_getschedparam(&attr, &param);
       if (s != 0)
           handle_error_en(s, "pthread_attr_getschedparam");
       s = pthread_attr_getschedpolicy(&attr, &policy);
       if (s != 0)
           handle_error_en(s, "pthread_attr_getschedpolicy");

       printf("Scheduler settings in \(aqattr\(aq\en");
       display_sched_attr(policy, &param);

       s = pthread_attr_getinheritsched(&attr, &inheritsched);
       printf("    inheritsched is %s\en",
               (inheritsched == PTHREAD_INHERIT_SCHED)  ? "INHERIT" :
               (inheritsched == PTHREAD_EXPLICIT_SCHED) ? "EXPLICIT" :
               "???");
       printf("\en");
   }

   /* Create a thread that will display its scheduling attributes */

   s = pthread_create(&thread, attrp, &thread_start, NULL);
   if (s != 0)
       handle_error_en(s, "pthread_create");

   /* Destroy unneeded thread attributes object */

   if (!use_null_attrib) {
     s = pthread_attr_destroy(&attr);
     if (s != 0)
         handle_error_en(s, "pthread_attr_destroy");
   }

   s = pthread_join(thread, NULL);
   if (s != 0)
       handle_error_en(s, "pthread_join");

   exit(EXIT_SUCCESS);
}
0

评论区