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