實時調(diào)度:操作系統(tǒng)在有限的時間內(nèi)提供特定水平的服務能力。受限制的響應時間不一定是塊的反應,意味著可預知的響應速度。如果系統(tǒng)定義_POSIX_THRAED_PRIORITY_SCHEDULING,它為線程指派實時調(diào)度優(yōu)先級提供支持。支持_POSIX_THRAED_PRIORITY_SCHEDULING的系統(tǒng)必須提供至少包括成員seched_priority的struct? sched_param結(jié)構(gòu)體的定義,seched_priority的標準策略是SCHED_FIFO和SCHED_RR使用的唯一參數(shù)。
影響實時調(diào)度:調(diào)度策略,參數(shù),競爭范圍和分配域
實時調(diào)度在某種程度上不一定很快,實時調(diào)度可能會變得很慢,因為它包含了更多搶占檢查的開銷特別是在一臺多處理機上
固定優(yōu)先級調(diào)度可能會導致優(yōu)先級倒置,優(yōu)先級倒置——低優(yōu)先級線程阻塞高優(yōu)先級線程運行,他是調(diào)度和同步之間一個不干凈的相互作用的結(jié)果。調(diào)用要求一個線程運行,但是同步要求運用另行的線程,所以兩個優(yōu)先級好像顛倒。如:一個低優(yōu)先級線程獲互斥資源,并且被一個隨后在同樣資源阻塞的高優(yōu)先級線程搶占時,優(yōu)先級發(fā)生倒置,在只有兩個線程被允許運行時,低優(yōu)先級線程被先執(zhí)行,然后釋放互斥量,如果在他們之間有第三個線程準備好時,他能阻塞低優(yōu)先級線程運行,因為低優(yōu)先級線程擁有高優(yōu)先級線程擁有的互斥量,中間優(yōu)先級線程阻止了高優(yōu)先級線程的執(zhí)行
優(yōu)先級調(diào)度不完全可移植。如:使用系統(tǒng)競爭范圍時,你的線程可以直接與操作系統(tǒng)內(nèi)核線程相競爭,提高自定義線程的優(yōu)先級可能會阻止內(nèi)核I/O驅(qū)動在系統(tǒng)上的一些工作
確實需要使用優(yōu)先級調(diào)度時(一般避免使用,因為相比解決問題,他會引起更多的問題),應記住:
進程競爭范圍比系統(tǒng)競爭范圍“更好”,因為你不會阻止其他進程或內(nèi)核中的某個線程運行 SCHED_RR比SCHED_FIFO“更好”,并且具有可移植性,因為SCHED_RR線程將在具有相同優(yōu)先級線程共享可用處理器時間間隔中被搶占 對SCHED_FIFO和SCHED_RR而言,低優(yōu)先級比高優(yōu)先級更好,因為能更少的妨礙另外重要的東西 // 1.設置的最高和最低優(yōu)先級,policy: 可以取三個值(SCHED_FIFO、SCHED_RR、SCHED_OTHER)
int sched_get_priority_max(
int policy);
int sched_get_priority_min(
int policy); // 2.設置和獲取優(yōu)先級
// param是struct sched_param類型的指針,它僅僅包含一個成員變sched_priority,指明所要設置的靜態(tài)線程優(yōu)先級。
int pthread_attr_setschedparam(pthread_attr_t *attr,
const struct sched_param *
param);
int pthread_attr_getschedparam(
const pthread_attr_t *attr,
struct sched_param *
param);
param.sched_priority =
51 ;
// 設置優(yōu)先級
struct sched_param
{ int __sched_priority;
// 所要設定的線程優(yōu)先級
}; // 3.改變策略(靜態(tài)改變策略和設置優(yōu)先級)
int pthread_attr_setschedpolicy(pthread_attr_t *attr,
int policy);
int pthread_attr_getschedpolicy(pthread_attr_t *attr,
int policy); // 4.繼承調(diào)度屬性,該屬性控制了你創(chuàng)建的線程從創(chuàng)建線程那繼承調(diào)度信息,schedpolicy和schedparam顯示設置調(diào)度信息
// 我手動設置了調(diào)度策略或優(yōu)先級時,必須顯示的設置線程調(diào)度策略的inheritsched屬性,因為pthread沒有為inheritsched設置默認值
// 所以在改變了調(diào)度策略或優(yōu)先級時必須總是設置該屬性。
int pthread_attr_setinheritsched(pthread_attr_t *attr,
int inheritsched);
int pthread_attr_getinheritsched(pthread_attr_t *attr,
int *
inheritsched);
/*
第一個函數(shù)中inheritsched的取值為:PTHREAD_INHERIT_SCHED 或者 PTHREAD_EXPLICIT_SCHED。
前者為繼承創(chuàng)建線程的調(diào)度策略和優(yōu)先級,后者指定不繼承調(diào)度策略和優(yōu)先級,而是使用自己設置的調(diào)度策略和優(yōu)先級。
無論何時,當你需要控制一個線程的調(diào)度策略或優(yōu)先級時,必須將inheritsched屬性設置為PTHREAD_EXPLICIT_SCHED。
*/ // 5.置正在運行的線程的調(diào)度策略和優(yōu)先級(動態(tài)設置線程的調(diào)度策略和優(yōu)先級)
// 前面的那些函數(shù)只能通過線程的屬性對象 pthread_attr_t 來設置線程的調(diào)度策略和優(yōu)先級,不能夠直接設置正在運行的線程的調(diào)度策略和優(yōu)先級
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);
// 在成功完成之后返回零。其他任何返回值都表示出現(xiàn)了錯誤。如果出現(xiàn)以下任一情況,pthread_setschedparam() 函數(shù)將失敗并返回
// 相應的值--EINVAL所設置屬性的值無效。ENOTSUP--嘗試將該屬性設置為不受支持的值。
// int pthread_setschedparam:thread參數(shù)所指向的線程不存在
// int pthread_getschedparam:1.參數(shù)policy或同參數(shù)policy關(guān)聯(lián)的調(diào)度參數(shù)之一無效; // 2.數(shù)policy或調(diào)度參數(shù)之一的值不被支持; // 3.調(diào)用線程沒有適當?shù)臋?quán)限來設置指定線程的調(diào)度參數(shù)或策略 // 4.參數(shù)thread指向的線程不存在;5.實現(xiàn)不允許應用程序?qū)?shù)改動為特定的值 SCHED_OTHER(是Linux默認的分時調(diào)度策略): 它是默認的線程分時調(diào)度策略,所有的線程的優(yōu)先級別都是0(不使用sched_param結(jié)構(gòu)體的sched_priority成員),如果系統(tǒng)使用這種調(diào)度策略,程序?qū)o法設置線程的優(yōu)先級 。這種調(diào)度策略也是搶占式的,當高優(yōu)先級的線程準備運行的時候,當前線程將被搶占并進入等待隊列。這種調(diào)度策略僅僅決定線程在可運行線程隊列中的具有相同優(yōu)先級的線程的運行次序。(使用此方式的代碼不可移植)SCHED_FIFO: 它是一種實時的先進先出調(diào)用策略,且只能在超級用戶下運行。這種調(diào)用策略僅僅被使用于優(yōu)先級大于0的線程。使用SCHED_FIFO的線程運行到有更高級的線程準備好或者愿意自己阻塞為止;當有一個線程準備好時,除非有平等或更高級的線程準備好,否則他將很快運行自己。 如果有若干相同優(yōu)先級的線程等待執(zhí)行,然而最早執(zhí)行的線程無終止或者阻塞動作,那么其他線程是無法執(zhí)行的,除非當前線程調(diào)用如pthread_yield之類的函數(shù),所以在使用SCHED_FIFO 的時候要小心處理相同級別線程的動作。SCHED_RR: 若有一個此類的線程運行超過一定的時間沒有阻塞,而另外的SCHED_RR或SCHED_FIFO策略相同優(yōu)先級的線程準備好時,運行的線程將被槍占意識準備好的線程運行。對于 SCHED_OTHER 策略,sched_priority 只能為 0。對于 SCHED_FIFO,SCHED_RR 策略,sched_priority?從 1 到 99。 調(diào)度策略和優(yōu)先級是分開來描述的。前者使用預定義的SCHED_RR、SCHED_FIFO、SCHED_OTHER,后者是通過結(jié)果體struct sched_param給出的。 這些設置調(diào)度策略和優(yōu)先級的函數(shù)操作的對象是線程的屬性pthread_attr_t,而不是直接來操作線程的調(diào)度策略和優(yōu)先級的。函數(shù)的第一個參數(shù)都是pthread_attr_t。 當pthread_setschedparam函數(shù)的參數(shù)?policy == SCHED_RR 或者 SCHED_FIFO 時,程序必須要在超級用戶下運行 pthread_setschedparam?函數(shù)改變在運行線程的調(diào)度策略和優(yōu)先級肯定就不用調(diào)用函數(shù)來設置inheritsched屬性了:pthread_attr_setinheritsched(&thread_attr,?PTHREAD_EXPLICIT_SCHED);?因為該函數(shù)設置的對象是pthread_attr_t? 當在對象屬性中設置調(diào)度策略或優(yōu)先級時,必須同時設置inheritsched屬性 改變線程屬性中調(diào)度策略和參數(shù)時是兩個操作,修改調(diào)度策略和修改參數(shù) 不能獨立于線程的參數(shù)來修改一個可執(zhí)行線程的調(diào)度策略,為了調(diào)度正確操作,參略和參數(shù)一定是一致的,每個調(diào)度策略有一個優(yōu)先級的唯一范圍,并且一個線程不能對一個對當前調(diào)度策略而言無效的優(yōu)先級執(zhí)行。 競爭范圍和分配域 int pthread_attr_getscope(pthread_attr_t *attr,
int *
scope); /* 返回值:若是成功返回0,否則返回錯誤的編號形 參:attr 指向一個線程屬性的指針scope 返回線程的作用域 */
// 指定了線程與誰競爭資源
int pthread_attr_setscope(pthread_attr_t *attr,
int scope); /* 返回值:若是成功返回0,否則返回錯誤的編號attr 指向一個線程屬性的指針guardsize 線程的作用域,可以取如下值PTHREAD_SCOPE_SYSTEM 與系統(tǒng)中所有進程中線程競爭PTHREAD_SCOPE_PROCESS 與當前進程中的其他線程競爭 */ 競爭范圍:描述了線程為處理資源而競爭的方式,系統(tǒng)競爭范圍意味著線程與進程之外的線程競爭處理器資源,一個進程內(nèi)的高優(yōu)先級系統(tǒng)競爭范圍線程能阻止其他進程內(nèi)的系統(tǒng)競爭范圍運行。競爭范圍指的是僅僅在同一進程內(nèi)相互競爭。
分配域:系統(tǒng)內(nèi)線程可以為其他競爭的處理器的集合。一個系統(tǒng)可以有一個以上的分配域,每個包含一個以上的處理器,在一個單處理器的處理機上,各個分配域可以包含從一個處理器到系統(tǒng)中所有的處理器。(沒有實現(xiàn)該接口)
競爭范圍內(nèi)的線程可以共享一個核實體 系統(tǒng)競爭范圍線程之間的環(huán)境切換通常要求至少一次內(nèi)核調(diào)用 競爭范圍在優(yōu)先級調(diào)度上沒有給你真正的控制——高優(yōu)先級的線程可以優(yōu)先于進程內(nèi)的其他線程運行 當一個線程被分配超過一個處理機的分配域時,應用程序不能完全依靠可預知的調(diào)度行為;如:高優(yōu)先級和低優(yōu)先級可以同時運行,調(diào)度程序不允許因為一個高優(yōu)先級的線程正在運行而是處理及閑置,單處理機行為在一臺多處理機上沒什么意思。 ?相關(guān)優(yōu)先級互斥量 不僅避免實時調(diào)度可以避免優(yōu)先級倒置,而且用互斥量加鎖協(xié)議也可以避免優(yōu)先級倒置
#if defined (_POSIX_THREAD_PRIO_PROSTECT) \||
defined (_POSIX_THREAD_PRIO_INHERIT)
int pthread_mutexattr_getprotocol(
const pthread_mutexattr_t *attr,
int *
protocol);
int pthread_mutexattr_setprotocol(
const pthread_mutexattr_t *attr,
int protocol);
#endif #if defined _POSIX_THREAD_PRIO_PROTECT
int pthread_mutexattr_getprioceiling(
const pthread_attr_t *attr,
int *
prioceiling);
int pthread_mutexattr_setprioceiling(
const pthread_attr_t *attr,
int prioceiling); int pthread_mutex_getprioceiling(
const pthread_attr_t *attr,
int *
prioceiling);
int pthread_mutex_getprioceiling(
const pthread_attr_t *attr,
int prioceiling);
#endif 加鎖或等待這些屬性之一的某個互斥量可以改變線程的優(yōu)先級——或另外優(yōu)先級的到來,來保證互斥量的線程不能被需要鎖住相同互斥量的其他線程搶占。 _POSIX_THREAD_PRIO_PROSTECT和_POSIX_THREAD_PRIO_INHERIT這些宏定義在<unistd.h>中,對應用進行條件編譯,活用sysconf來檢查。 一旦創(chuàng)建了使用這些屬性之一的互斥量,就能對任何其他互斥量一樣來枷鎖和解鎖互斥量,使用pthread_mutex_init就能變換創(chuàng)建的互斥量 如果定義_POSIX_THREAD_PRIO_PROSTECT,則它支持“優(yōu)先級ceiling協(xié)議”和prioceiling屬性,通過調(diào)用pthread_mutexattr_setprotocol設置協(xié)議屬性,如果將協(xié)議屬性設置為_POSIX_THREAD_PRIO_PROSTECT,則可以通過設置prioceiling屬性使用屬性對象創(chuàng)建互斥量優(yōu)先級設置ceiling。 調(diào)用pthread_mutexattr_setprioceiling設置prioceiling屬性,當任何線程鎖住與該屬性對象相關(guān)定義的一個互斥量時,線程的優(yōu)先級將被設置為互斥量的優(yōu)先級ceiling,除非線程的優(yōu)先級已經(jīng)是相同或更高,在高于互斥量優(yōu)先級ceiling的線程內(nèi)加鎖該互斥量會被打破協(xié)議,失去對優(yōu)先級倒置的保護 優(yōu)先級繼承:當一個線程再由另個低優(yōu)先級線程擁有的互斥量上等待時,后者優(yōu)先級將被增加到等待線程的優(yōu)先級。 如果定義_POSIX_THREAD_PRIO_INHERIT他就支持協(xié)議屬性,如果將屬性設置為_POSIX_THREAD_PRIO_INHERIT,那么保持互斥量的線程就不能被另外的與等待互斥量的線程相比優(yōu)先級低的任何線程搶占,當任何線程加鎖互斥量,同時一個低優(yōu)先級的線程擁有互斥量時,只要它擁有互斥量,當前擁有互斥量的線程的優(yōu)先級將被提高到等待線程的優(yōu)先級 優(yōu)先級ceiling互斥量 當使用優(yōu)先級ceiling創(chuàng)建一個互斥量時,指定的線程鎖住互斥量時可以擁有最高的優(yōu)先級,任何鎖住互斥量的線程將自動將它的優(yōu)先級值提高到那個值,這允許在他被任何另外試圖加鎖該互斥量的線程搶占以前,完成對互斥量的操作。
一個優(yōu)先級ceiling互斥量在一個庫函數(shù)中無法使用。
如果有任何比ceiling高的優(yōu)先級運行的線程鎖住優(yōu)先級ceiling互斥量,協(xié)議將被破壞。
優(yōu)先級繼承互斥量 當一個線程鎖住互斥量時,線程的優(yōu)先級就被互斥量控制,當另外的線程在那個互斥量上阻塞時,他會查看擁有互斥量的線程優(yōu)先級,如果擁有互斥量的線程比試圖在互斥量上阻塞的線程優(yōu)先級低,則擁有互斥量的線程的優(yōu)先級將被提升到阻塞線程的優(yōu)先級。
除非等待的線程也被搶占,提高優(yōu)先級確保擁有互斥量的線程不能被搶占;擁有互斥量的線程代表的是高優(yōu)先級工作的線程,當線程互斥量解鎖時,線程的優(yōu)先級被自動降到他原來的優(yōu)先級,高優(yōu)先級等待線程將被喚醒,如果又有一個高優(yōu)先級線程在互斥量上阻塞,擁有互斥量的線程將再次增加優(yōu)先級。
核實體 線程:調(diào)用pthread_create創(chuàng)建的一個線程,類行為pthread_t的一個標識符代表,使用pthreads接口可控制
處理機:物理硬件
核實體:線程和處理機間的一層附加抽象,可能是一個傳統(tǒng)的UNIX進程。
線程與核實體的交互方式:多對一(用戶級),一對一(內(nèi)核級),多對少
轉(zhuǎn)載于:https://www.cnblogs.com/tianzeng/p/9192706.html
總結(jié)
以上是生活随笔 為你收集整理的pthread调度策略,优先级和竞争范围 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。