1. 程式人生 > >執行緒排程演算法和優先順序

執行緒排程演算法和優先順序

函式pthread_attr_setschedpolicypthread_attr_getschedpolicy分別用來設定和得到執行緒的排程策略。

名稱:

pthread_attr_getschedpolicy

pthread_attr_setschedpolicy

功能:

獲得/設定執行緒的排程策略

標頭檔案:

#include <pthread.h>

函式原形:

int pthread_attr_getschedpolicy(const pthread_attr_t *attr,int *policy);

int pthread_attr_setschedpolicy(pthread_attr_t *attr,int policy);

引數:

attr          執行緒屬性變數

policy        排程策略

返回值:

若成功返回0,若失敗返回-1

這兩個函式具有兩個引數,第1個引數是指向屬性物件的指標,第2個引數是排程策略或指向排程策略的指標。排程策略可能的值是先進先出(SCHED_FIFO)、輪轉法(SCHED_RR,或其它(SCHED_OTHER)。

       SCHED_FIFO策略允許一個執行緒執行直到有更高優先順序的執行緒準備好,或者直到它自願阻塞自己。在SCHED_FIFO排程策略下,當有一個執行緒準備好時,除非有平等或更高優先順序的執行緒已經在執行,否則它會很快開始執行。

    SCHED_RR(輪循)策略是基本相同的,不同之處在於:如果有一個SCHED_RR

策略的執行緒執行了超過一個固定的時期(時間片間隔)沒有阻塞,而另外的SCHED_RRSCHBD_FIPO策略的相同優先順序的執行緒準備好時,執行的執行緒將被搶佔以便準備好的執行緒可以執行。

當有SCHED_FIFOSCHED_RR策賂的執行緒在一個條件變數上等待或等待加鎖同一個互斥量時,它們將以優先順序順序被喚醒。即,如果一個低優先順序的SCHED_FIFO執行緒和一個高優先織的SCHED_FIFO執行緒都在等待相同的互斥鎖,則當互斥量被解鎖時,高優先順序執行緒將總是首先被解除阻塞。

執行緒的排程引數

函式pthread_attr_getschedparampthread_attr_setschedparam分別用來設定和得到執行緒的排程引數。

名稱:

pthread_attr_getschedparam

pthread_attr_setschedparam

功能:

獲得/設定執行緒的排程引數

標頭檔案:

#include <pthread.h>

函式原形:

int pthread_attr_getschedparam(const pthread_attr_t *attr,struct sched_param *param);

int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);

引數:

attr          執行緒屬性變數

param          sched_param結構

返回值:

若成功返回0,若失敗返回-1

這兩個函式具有兩個引數,第1個引數是指向屬性物件的指標,第2個引數是sched_param結構或指向該結構的指標。結構sched_param在檔案/usr/include /bits/sched.h中定義如下:

struct sched_param

{

       int _sched_priority;

};

結構sched_param的子成員sched_priority控制一個優先權值,大的優先權值對應高的優先權。系統支援的最大和最小優先權值可以用sched_get_priority_max函式和sched_get_priority_min函式分別得到。

注意:如果不是編寫實時程式,不建議修改執行緒的優先順序。因為,排程策略是一件非常複雜的事情,如果不正確使用會導致程式錯誤,從而導致死鎖等問題。如:在多執行緒應用程式中為執行緒設定不同的優先級別,有可能因為共享資源而導致優先順序倒置。

名稱:

sched_get_priority_max

sched_get_priority_min

功能:

獲得系統支援的執行緒優先權的最大和最小值

標頭檔案:

#include <pthread.h>

函式原形:

int sched_get_priority_max(int policy);

int sched_get_priority_min(int policy);

引數:

policy呼叫策略          

返回值:

執行緒優先權的最大和最小值

例項如下:

#include <pthread.h>

#include <sched.h>

void *child_thread(void *arg)

{

int policy;

int max_priority,min_priority;

struct sched_param param;

pthread_attr_t attr;

pthread_attr_init(&attr); /*初始化執行緒屬性變數*/

#if 0

pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); /*設定執行緒繼承性*/

pthread_attr_getinheritsched(&attr,&policy); /*獲得執行緒的繼承性*/

if(policy==PTHREAD_EXPLICIT_SCHED)

    printf(“Inheritsched:PTHREAD_EXPLICIT_SCHED\n”);

if(policy==PTHREAD_INHERIT_SCHED)

    printf(“Inheritsched:PTHREAD_INHERIT_SCHED\n”);

 #endif

pthread_attr_setschedpolicy(&attr,SCHED_RR);/*設定執行緒排程策略*/

pthread_attr_getschedpolicy(&attr,&policy);/*取得執行緒的排程策略*/

 switch ( policy )
    {
        case SCHED_FIFO:
                printf("policy = SCHED_FIFO\n");
                break;
        case SCHED_RR:
                printf("policy = SCHED_RR\n");
                break;
        case SCHED_OTHER:
                printf("policy = SCHED_OTHER\n");
                break;
        default:
                printf("policy = UNKNOWN\n");
                break;
    }

max_priority = sched_get_priority_max(policy);   /*獲得系統支援的執行緒優先權的最大值*/
min_priority = sched_get_priority_min(policy);    /* 獲得系統支援的執行緒優先權的最小值*/

printf(“Max priority:%u\n”,max_priority);

printf(“Min priority:%u\n”,min_priority);

param._sched_priority=max_priority;   //或者將此函式增加引數,將max_priority換成函式的引數值,

                                                           //(min_priority, max_priority)區間內的值

pthread_attr_setschedparam(&attr,&param);/*設定執行緒的排程引數*/

printf(“sched_priority:%u\n”,param._sched_priority);/*獲得執行緒的排程引數*/

pthread_attr_destroy(&attr);

}

int main(int argc,char *argv[ ])

{

pthread_t child_thread_id;

pthread_create(&child_thread_id,NULL,child_thread,NULL);

pthread_join(child_thread_id,NULL);

}

inherit [英]ɪn'herɪt
vt. vi. 繼承


執行緒是獨立執行的。它們被分派到處理器核心上,並執行分給它們的任務。每個執行緒均有一個排程策略和優先順序,決定何時以及如何分配到處理器上。執行緒或執行緒組的排程策略可以使用這些函式通過屬性物件來設定:

呼叫形式

  1. #include <pthread.h> 
  2. #include <sched.h>
  3. int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);  
  4. void pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);  
  5. int pthread_attr_setschedparam(pthread_attr_t *restrict attr,  
  6.                          const struct sched_param *restrict param); 

pthread_attr_setinheritesched( )用於確定如何設定執行緒的排程屬性,可以從建立者執行緒或從一個屬性物件來繼承排程屬性。inheritsched可以為如下值。

PTHREAD_INHERIT_SCHED:執行緒排程屬性是從建立者執行緒繼承得到,attr的任何排程屬性都被忽略。

PTHREAD_EXPLICIT_SCHED:執行緒排程屬性設定為屬性物件attr的排程屬性。

如果inheritsched值是PTHREAD_EXPLICIT_SCHED,則pthread_attr_setschedpolicy( )被用於設定排程策略,而pthread_attr_setschedparam( )被用於設定優先順序。

pthread_attr_setschedpolicy( )設定執行緒屬性物件attr的排程策略。policy的值可以為在<sched.h>標頭檔案中定義的以下值。

SCHED_FIFO:先進先出排程策略,執行執行緒執行到結束。

SCHED_RR:輪詢排程策略,按照時間片將每個執行緒分配到處理器上。

SCHED_OTHER:另外的排程策略(根據實現定義)。這是任何新建立執行緒的預設排程策略。

使用pthread_attr_setschedparam( )可以設定排程策略所使用的屬性物件attr的排程引數。param是包含引數的結構體。sched_param結構體至少需要定義這個資料成員:

  1. struct sched_param {  
  2.    int sched_priority;  
  3.    //...  
  4. }; 

它可能還有其他的資料成員,以及多個用來返回和設定最小優先順序、最大優先順序、排程器、引數等的函式。如果排程策略是SCHED_FIFO或SCHED_RR,那麼要求具有值的唯一成員是sched_priority。

按照如下方法使用sched_get_priority_max( )和sched_get_priority_max( ),可以得到優先順序的最大值和最小值。

呼叫形式

  1. #include <sched.h> 
  2. int sched_get_priority_max(int policy);  
  3. int sched_get_priority_min(int policy); 

兩個函式都以排程策略policy為引數,目的是獲得對應排程策略的優先順序值,而且都返回排程策略的最大或最小優先順序值。

示例6-10顯示瞭如何使用執行緒屬性物件設定執行緒的排程策略和優先順序。

示例6-10

  1. // Example 6-10 Using the thread attribute object to set scheduling  
  2. // policy and priority of a thread.  
  3. #include <pthread.h>
  4. #include <sched.h>
  5. //...  
  6. pthread_t ThreadA;  
  7. pthread_attr_t SchedAttr;  
  8. sched_param SchedParam;  
  9. int MidPriority,MaxPriority,MinPriority;  
  10. int main(int argc, char *argv[])  
  11. {  
  12.    //...  
  13.    // Step 1: initialize attribute object  
  14.    pthread_attr_init(&SchedAttr);  
  15.    // Step 2: retrieve min and max priority values for scheduling policy  
  16. MinPriority = sched_get_priority_max(SCHED_RR);  
  17. MaxPriority = sched_get_priority_min(SCHED_RR);  
  18.    // Step 3: calculate priority value  
  19. MidPriority = (MaxPriority + MinPriority)/2;  
  20.    // Step 4: assign priority value to sched_param structure  
  21. SchedParam.sched_priority = MidPriority;  
  22.    // Step 5: set attribute object with scheduling parameter  
  23.    pthread_attr_setschedparam(&SchedAttr,&SchedParam);  
  24.    // Step 6: set scheduling attributes to be determined by attribute object  
  25.    pthread_attr_setinheritsched(&SchedAttr,PTHREAD_EXPLICIT_SCHED);  
  26.    // Step 7: set scheduling policy  
  27.    pthread_attr_setschedpolicy(&SchedAttr,SCHED_RR);  
  28.    // Step 8: create thread with scheduling attribute object  
  29.    pthread_create(&ThreadA,&SchedAttr,task1,NULL);  
  30.    //...  

在示例6-10中,ThreadA的排程策略和優先順序是使用執行緒屬性物件SchedAttr來設定的。通過8個步驟完成:

(1) 初始化屬性物件

(2) 為排程策略提取最大和最小優先順序值

(3) 計算優先順序值

(4) 將優先順序值賦給sched_param結構體

(5) 使用排程引數設定屬性物件

(6) 將排程屬性設定為由屬性物件決定

(7) 設定排程策略

(8) 使用排程屬性物件建立一個執行緒

在示例6-10中,我們將優先順序設定為一個平均值。但是優先順序可以設定為介於執行緒排程策略所允許的最大和最小優先順序值之間的任何值。有了這些方法,排程策略和優先順序可以線上程被建立或執行之前,先設定線上程屬性物件中。為了動態改變排程策略和優先順序,可以使用pthread_setschedparam( )和pthread_setschedprio( )。

呼叫形式

  1. #include <pthread.h> 
  2. int pthread_setschedparam(pthread_t thread, int policy,  
  3.                           const struct sched_param *param);  
  4. int pthread_getschedparam(pthread_t thread, int *restrict policy,  
  5.                           struct sched_param *restrict param);  
  6. int pthread_setschedprio(pthread_t thread, int prio); 

pthread_setschedparam( )不需要使用屬性物件即可直接設定執行緒的排程策略和優先順序。thread是執行緒的id,policy是新的排程策略,param包含排程優先順序。如果成功,則pthread_getschedparam( )返回排程策略和排程引數,並將它們的值分別儲存在policy和param引數中。如果成功,則兩個函式都返回0。如果不成功,兩個函式都返回錯誤號。表6-7列出了這些函式可能失敗的條件。

pthread_setschedprio( )用來設定正在執行中的執行緒的排程優先順序,該程序的id由thread指定。prio指定了執行緒的新排程優先順序。如果函式失敗,執行緒的優先順序不發生變化,返回一個錯誤號。如果成功,則函式返回0。表6-7也列出了這個函式可能失敗的條件。

表6-7

pthread排程和優先順序函式

失敗的條件

int pthread_getschedparam

(pthread_t thread,

int *restrict policy, struct

sched_param *restrict param);

thread引數所指向的執行緒不存在

int pthread_setschedparam

(pthread_t thread,

int *policy, const

struct sched_param *param);

引數policy或同參數policy

關聯的排程引數之一無效;

引數policy或排程引數之一的值不被支援;

呼叫執行緒沒有適當的許可權來設

置指定執行緒的排程引數或策略;

引數thread指向的執行緒不存在;

實現不允許應用程式將引數

改動為特定的值

int pthread_setschedprio

(pthread_t thread, int prio);

引數prio對於指定執行緒的排程策略無效;

引數prio的值不被支援;

呼叫執行緒沒有適當的許可權來設

置指定執行緒的排程優先順序;

引數thread指向的執行緒不存在;

實現不允許應用程式將優先

級改變為指定的值


注意:

要記得仔細考慮為何有必要改變執行執行緒的排程策略或優先順序。這可能會嚴重影響應用程式的總體效能。有著較高優先順序的執行緒會搶佔執行的較低優先順序的執行緒。這可能會產生餓死,即執行緒持續被搶佔,因此無法完成執行


相關推薦

執行排程演算法優先順序

函式pthread_attr_setschedpolicy和pthread_attr_getschedpolicy分別用來設定和得到執行緒的排程策略。 名稱:: pthread_attr_getschedpolicy pthread_attr_setschedpol

執行排程排程策略

執行緒排程器(Thread Scheduler):     作業系統的核心,它實際上就是一個常駐記憶體的程式,不斷地對執行緒佇列進行掃描,利用特定演算法 (時間片輪轉法、優先順序排程法、多

執行排程演算法

我們可能經常會用到 Sleep 函式來使執行緒掛起一段時間。那麼你有沒有正確的理解這個函式的用法呢?思考下面這兩個問題: 假設現在是 2012-12-16 3:37:40,如果我呼叫一下 Thread.Sleep(1000) ,在 2012-12-16 3:37:41

執行排程優先順序

linux核心排程三種策略: 1,SCHED_OTHER 分時排程策略, 2,SCHED_FIFO實時排程策略,先到先服務 3,SCHED_RR實時排程策略,時間片輪轉 分時程序則通過nice和counter值決定權值,nice越小,counter越大,被排程的概率越大,也就是曾

Windows核心程式設計筆記(七) 執行排程 優先順序 關聯性

在搶佔式多工作業系統中,執行緒的執行是有限制的,系統會排程一個執行緒在一個時間塊內佔用CPU,在時間到了之後將執行緒的上下文(CONTEXT結構,儲存執行緒切換前的CPU個暫存器的值)儲存到執行緒核心物件中,從另一個可排程執行緒的CONTEXT中獲取屬於它的CPU各暫存器

RxJava RxAndroid 五(執行排程

對rxJava不瞭解的同學可以先看 本文將有幾個例子說明,rxjava執行緒排程的正確使用姿勢。 例1 Observable .create(new Observable.OnSubscribe<String>() {

Windows核心程式設計筆記(5)----執行排程優先順序

1、作業系統執行緒排程過程 每個執行緒都有一個上下文CONTEXT結構體,儲存線上程的核心物件中,這個上下文中儲存了執行緒上一次執行時CPU暫存器的狀態。每隔固定時間,Windows會檢視所有當前存在的執行緒核心物件,其中只有一些是可排程的。Windows在可排程的執行緒中

對Nachos執行排程的探討改進

nachos執行緒排程例項剖析 為了有效的管理CPU資源在處理Nachos執行緒排程的修改問題上,首先應該著重考慮這樣幾個問題:何時進行執行緒排程?遵循何種規則完成排程?以及排程過程中需要完成哪些工作?同時要兼顧執行緒排程的考量標準,即響應時間、週轉時間、CPU吞吐量等。排程

如何實現一個執行排程框架

一、前言 執行緒是程式執行流的最小單元,很基礎,也很重要。為了提高流暢性,耗時任務放後臺執行緒執行,這是APP開發的常識了。隨著APP複雜度的提升,越來越多工需要開執行緒執行,同時,遇到如下挑戰: 任務場景多樣化,常規的API無法滿足; 隨著元件化,模組化等演進,可能使得執行緒管理不統一(比如多

執行學習---CallableFuture的使用(十)

1.Callable和Future適用於帶有返回結果的多執行緒 示例 public class CallAndFutureStudy { public static void main(String[] args) { ExecutorService threadPool

執行的同步非同步理解

//當個執行緒訪問同一個資源的時候,要注意執行緒同步的問題,如果不同步容易造成資料沒及時修改,然後就被另一個執行緒訪問,得到的資料還是上一次的資料,造成資料錯誤的情況,以下demo可以很容易發現,為了便於發現我在上面休眠100毫秒,如果將ticket設為方法內的區域性變數則就不會共享了。 pa

python執行中joinsetDaemon

join([timeout]) 主執行緒A中,建立子執行緒B,B呼叫join函式會使得主執行緒阻塞,直到子執行緒執行結束或超時。引數timeout是一個數值型別,用來表示超時時間,如果未提供該引數,那麼主調執行緒將一直阻塞直到子執行緒結束。 注意:必須在start() 方法呼叫之後設

【轉】【執行】sleep() wait() 的區別

https://blog.csdn.net/xyh269/article/details/52613507?utm_source=blogkpcl6   https://blog.csdn.net/lcore/article/details/12221217?utm_source=

執行的sleepyield

xl_echo編輯整理,歡迎轉載,轉載請宣告文章來源。更多IT、程式設計案例、資料請聯絡QQ:1280023003,加群298140694。百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這才是真正的堪稱強大!!! sleep 是一個靜態方法,觀察其原始碼可以看到,其中有兩個過

Java多執行-44-靜態非靜態方法同步鎖物件是什麼

前面一篇,我們知道了synchronized關鍵字擴起來範圍的程式碼塊就可以實現同步,其實,在Java中,只需要在方法上加上synchronized關鍵字即可,就像加上static一樣。本篇來看看加上synchronized關鍵字修飾的非靜態和靜態方法的同步鎖物件是什麼。 1.非靜態同步鎖物

從零開始學多執行之取消關閉(六)

小節 為什麼需要取消和關閉: 有時候我們希望在任務或執行緒自然結束之前就停止它們,可能因為使用者取消了操作,或者應用程式需要快速關閉. 取消和關閉的好處: 不會浪費資源執行一些沒用的操作、保證程式的正常退出. Java沒有提供任何機制,來安全地強迫執行緒停止手頭的工作.它提供中斷(執行緒

Java執行之semaphoreExchanger

Semaphore是Java執行緒的一個計數訊號量。我們可用於多執行緒的併發訪問控制。 就像我們常見的執行緒池,資料庫連線池就可以使用Semaphore進行邏輯的實現。Semaphore中我們就介紹兩個最常用的兩個方法。 acquire() 從Semaphore獲取許可,如果計數不小於0

一句話介紹python執行、程序協程

一、程序: Python的os模組封裝了常見的系統呼叫,其中就包括fork。而fork是linux常用的產生子程序的方法,簡言之是一個呼叫,兩個返回。 在python中,以下的兩個模組用於程序的使用。詳細就不展開。 multiprocessing:跨平臺版本的多程序模組。 Pool:程序池 Queu

Python學習筆記:threading.Condition多執行排程

#!/usr/bin/python #coding:utf-8 #引入執行緒和時間模組 import threading,time   #引入執行緒條件變數 cond = threading.Condition() def run():    

執行同步鎖非同步鎖的幾種方式

同步鎖:當在一個java虛擬機器多個執行緒操作一個變數的時候就會出現執行緒安全問題,這個時候就會用到同步鎖。 同步鎖的解決方式: 先看下一個執行緒異常的售票 public class ThreadSafe { public static void main(String[] arg