thread基本常识内容汇总

发布时间 2023-12-22 11:16:36作者: OzTaking

1.pthread_setschedparam

man 手册-来自Ubuntu20.04

PTHREAD_SETSCHEDPARAM(3)                                                                              Linux Programmer's Manual                                                                             PTHREAD_SETSCHEDPARAM(3)

NAME
       pthread_setschedparam, pthread_getschedparam - set/get scheduling policy and parameters of a thread
       /*设置/获取线程的调度策略和参数*/
SYNOPSIS
       #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);

       Compile and link with -pthread.

DESCRIPTION
        /*pthread_setschedparam()函数用于设置线程的调度策略和参数。*/
       The pthread_setschedparam() function sets the scheduling policy and parameters of the thread thread.

        /*policy指定线程的新调度策略。  sched(7)中描述了策略支持的值及其语义。*/
       policy specifies the new scheduling policy for thread.  The supported values for policy, and their semantics, are described in sched(7).

        /*param指向的结构指定线程的新调度参数。  计划参数在以下结构中维护:*/
       The structure pointed to by param specifies the new scheduling parameters for thread.  Scheduling parameters are maintained in the following structure:

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

        /*可以看出,仅支持一个调度参数。  各调度策略中调度优先级的允许范围详见sched(7)。*/
       As can be seen, only one scheduling parameter is supported.  For details of the permitted ranges for scheduling priorities in each scheduling policy, see sched(7).

       The pthread_getschedparam() function returns the scheduling policy and parameters of the thread thread, in the buffers pointed to by policy and param, respectively.  
       The returned priority value is that set by the most re‐cent pthread_setschedparam(), pthread_setschedprio(3), or pthread_create(3) call that affected thread.  
       The returned priority does not reflect any temporary priority adjustments as a result of calls to any priority inher‐itance or priority ceiling functions
        (see, for example, pthread_mutexattr_setprioceiling(3) and pthread_mutexattr_setprotocol(3)).

       /**
       pthread_getschedparam()函数返回线程的调度策略和参数,分别位于policy和param所指向的缓冲区中。          
       返回的优先级值是由受影响线程的最新pthread_setschedparam()、pthread_setschedprio(3)或pthread_create(3)调用设置的。          
       返回的优先级不反映调用任何优先级继承或优先级上限函数所导致的任何临时优先级调整         
       (参考例如,pthread_mutexattr_setprioceiling(3)和pthread_mutexattr_setprotocol(3))。
       */ 

RETURN VALUE
       On success, these functions return 0; on error, they return a nonzero error number.  If pthread_setschedparam() fails, the scheduling policy and parameters of thread are not changed.
        /*成功时,这些函数返回0;出错时,它们返回一个非零的错误数字。  如果pthread_setschedparam()失败,线程的调度策略和参数不会改变。*/
ERRORS
       Both of these functions can fail with the following error:

       ESRCH  No thread with the ID thread could be found.

       pthread_setschedparam() may additionally fail with the following errors:

       EINVAL policy is not a recognized policy, or param does not make sense for the policy.

       EPERM  The caller does not have appropriate privileges to set the specified scheduling policy and parameters.

       POSIX.1 also documents an ENOTSUP ("attempt was made to set the policy or scheduling parameters to an unsupported value") error for pthread_setschedparam().

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

       ESRCH 找不到具有此ID的线程。

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

            EINVAL  策略不是可识别的策略,或者param对于该策略没有意义。

            EPERM   调用方没有适当的权限来设置指定的调度策略和参数。

       POSIX.1还记录了pthread_setschedparam()的ENOTALK(“尝试将策略或调度参数设置为不受支持的值”)错误。
        */
ATTRIBUTES
       For an explanation of the terms used in this section, see attributes(7).

       ┌─────────────────────────┬───────────────┬─────────┐
       │Interface                │ Attribute     │ Value   │
       ├─────────────────────────┼───────────────┼─────────┤
       │pthread_setschedparam(), │ Thread safety │ MT-Safe │
       │pthread_getschedparam()  │               │         │
       └─────────────────────────┴───────────────┴─────────┘
CONFORMING TO
       POSIX.1-2001, POSIX.1-2008.

NOTES
       /*有关更改线程的调度策略和优先级所需的权限和影响的描述,以及每个调度策略中优先级的允许范围的详细信息,请参见sched(7)。*/
       For a description of the permissions required to, and the effect of, changing a thread's scheduling policy and priority, and details of the permitted ranges for priorities in each scheduling policy, see sched(7).

EXAMPLE
       /*下面的程序演示了pthread_setschedparam()和pthread_getschedparam()的用法,以及许多其他与线程相关的pthreads函数的用法。*/
       The program below demonstrates the use of pthread_setschedparam() and pthread_getschedparam(), as well as the use of a number of other scheduling-related pthreads functions.

        /*
        在接下来的运行中,主线程将其调度策略设置为优先级为10的SCHED_FIFO,并使用调度策略属性SCHED_RR和调度优先级属性20来初始化线程属性对象。  
        然后,程序将线程属性对象的inheritsched属性设置(使用pthread_attr_setinheritsched(3))为PTHREAD_EXPLICIT_SCHED,
        这意味着使用此属性对象创建的线程应从线程属性对象中获取其调度属性。 
        然后,程序使用线程属性对象创建一个线程,该线程将显示其调度策略和优先级。
        */
       In the following run, the main thread sets its scheduling policy to SCHED_FIFO with a priority of 10, and initializes a thread attributes object with a scheduling policy attribute of SCHED_RR and a scheduling priority at‐
       tribute  of  20.  The program then sets (using pthread_attr_setinheritsched(3)) the inherit scheduler attribute of the thread attributes object to PTHREAD_EXPLICIT_SCHED, meaning that threads created using this attributes
       object should take their scheduling attributes from the thread attributes object.  The program then creates a thread using the thread attributes object, and that thread displays its scheduling policy and priority.

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

           Scheduler settings in 'attr'
               policy=SCHED_RR, priority=20
               inheritsched is EXPLICIT // ----> 不同之处

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

       /*在上面的输出中,可以看到调度策略和优先级取自线程属性对象中指定的值。*/
       In the above output, one can see that the scheduling policy and priority were taken from the values specified in the thread attributes object.

       /*下一次运行与上一次运行相同,只是继承调度程序属性设置为PTHREAD_INHERIT_SCHED,这意味着使用线程属性对象创建的线程应忽略属性对象中指定的调度属性,而是从创建线程获取其调度属性*/
       The next run is the same as the previous, except that the inherit scheduler attribute is set to PTHREAD_INHERIT_SCHED, meaning that threads created using the thread attributes  object  should  ignore  the  scheduling  at‐
       tributes specified in the attributes object and instead take their scheduling attributes from the creating thread.

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

           Scheduler settings in 'attr'
               policy=SCHED_RR, priority=20
               inheritsched is INHERIT // ----> 不同之处

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

       /*在上面的输出中,可以看到调度策略和优先级来自创建线程,而不是线程属性对象。*/
       In the above output, one can see that the scheduling policy and priority were taken from the creating thread, rather than the thread attributes object.

       /*注意,如果我们省略了-i i选项,输出将是相同的,因为PTHREAD_INHERIT_SCHED是继承调度器属性的默认值。*/
       Note that if we had omitted the -i i option, the output would have been the same, since PTHREAD_INHERIT_SCHED is the default for the inherit scheduler attribute.

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

       static int
       get_policy(char p, int *policy)
       {
           switch (p) {
           case 'f': *policy = SCHED_FIFO;     return 1;
           case 'r': *policy = SCHED_RR;       return 1;
           case 'o': *policy = SCHED_OTHER;    return 1;
           default:  return 0;
           }
       }

       static void
       display_sched_attr(int policy, struct sched_param *param)
       {
           printf("    policy=%s, priority=%d\n",
                   (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\n", 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 'a': attr_sched_str = optarg;      break;
               case 'A': use_null_attrib = 1;          break;
               case 'i': inheritsched_str = optarg;    break;
               case 'm': main_sched_str = optarg;      break;
               default:  usage(argv[0], "Unrecognized option\n");
               }
           }

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

           /* 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)\n");
               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("\n");

           /* 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] == 'e')
                   inheritsched = PTHREAD_EXPLICIT_SCHED;
               else if (inheritsched_str[0] == 'i')
                   inheritsched = PTHREAD_INHERIT_SCHED;
               else
                   usage(argv[0], "Value for -i must be 'e' or 'i'\n");

               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 'attr' (-a)\n");
               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 'attr'\n");
               display_sched_attr(policy, &param);

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

           /* 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);
       }

SEE ALSO
       getrlimit(2), sched_get_priority_min(2), pthread_attr_init(3), pthread_attr_setinheritsched(3), pthread_attr_setschedparam(3), pthread_attr_setschedpolicy(3), pthread_create(3), pthread_self(3), pthread_setschedprio(3),
       pthreads(7), sched(7)

COLOPHON
       This page is part of release 5.05 of the Linux man-pages project.  A description of the project, information about reporting bugs, and the latest version of this page, can be found at
       https://www.kernel.org/doc/man-pages/.

Linux                                                                                                        2019-03-06                                                                                     PTHREAD_SETSCHEDPARAM(3)

在ubuntu上代码测试,工具clion

 源码就是上面的man手册的源码

运行结果:

Scheduler settings of main thread
    policy=SCHED_FIFO, priority=10

Scheduler settings in 'attr'
    policy=SCHED_RR, priority=20
    inheritsched is INHERIT

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

 运行结果:

Scheduler settings of main thread
    policy=SCHED_FIFO, priority=10

Scheduler settings in 'attr'
    policy=SCHED_RR, priority=20
    inheritsched is INHERIT

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