Linux多線程實踐(三)線程的基本屬性設定API

來源:互聯網
上載者:User

標籤:pre   get   包含   並發   sso   釋放   決定   ble   失效   

POSIX 線程庫定義了線程屬性對象 pthread_attr_t ,它封裝了線程的建立者能夠訪問和改動的線程屬性。主要包含例如以下屬性:

1. 範圍(scope)

2. 棧尺寸(stack size)

3. 棧地址(stack address)

4. 優先順序(priority)

5. 分離的狀態(detached state)

6. 調度策略和參數(scheduling policy and parameters)


 線程屬性對象能夠與一個線程或多個線程相關聯。當使用線程屬性對象時。它是對線程和線程組行為的配置。使用屬性對象的全部線程都將具有由屬性對象所定義的全部屬 性。儘管它們共用屬性對象。但它們維護各自獨立的線程 ID 和寄存器。

初始化/銷毀線程屬性

int pthread_attr_init(pthread_attr_t *attr);  int pthread_attr_destroy(pthread_attr_t *attr);  
線程分離屬性
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);  int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);  
線程棧大小
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);  int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);

普通情況下該值我們設定為0,使用系統預設設定的線程棧大小。否則可能會引起程式的可移植性的問題

線程棧溢出保護區大小
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);  int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);  

guardsize意思是假設我們使用線程棧超過了設定大小之後,系統還會使用部分擴充記憶體來防止棧溢出。而這部分擴充記憶體大小就是guardsize. 只是假設自己改動了棧分配位置的話,那麼這個選項失效,效果相當於將guardsize設定為0.

每一個線程都存在自己的堆棧。假設這些堆棧是相連的話,訪問超過自己的堆棧的話那麼可能會改動到其它線程的堆棧。 假設我們設定了guardsize的話,線程堆棧會多開闢guarszie大小的記憶體,當訪問到這塊記憶體時會觸發SIGSEGV訊號。

線程競爭範圍(進程範圍內的競爭 or 系統範圍內的競爭)
int pthread_attr_getscope(const pthread_attr_t *attr,int *contentionscope);  int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);  

線程能夠在兩種競爭域內競爭資源:

1. 進程域(process scope):與同一進程內的其它線程

2. 系統域(system scope):與系統中的全部線程

範圍屬性描寫敘述特定線程將與哪些線程競爭資源。一個具有系統域的線程將與整個系 統中全部具有系統域的線程依照優先順序競爭處理器資源,進行調度。

線程調度策略

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

進程的調度策略和優先順序屬於主線程,換句話說就是設定進程的調度策略和優先順序僅僅 會影響主線程的調度策略和優先順序。而不會改變對等線程的調度策略和優先順序(注這句話不全然正確)。

每一個對等線程能夠擁有它自己的獨立於主線程的調度策略和優先順序。

在 Linux 系統中,進程有三種調度策略:SCHED_FIFO(先進先出調度策略)、SCHED_RR(時間片輪轉調度演算法) 和 SCHED_OTHER(線程一旦開始執行,直到被搶佔或者直到線程堵塞或停止為止)。線程也不例外。也具有這三種策略。

線程繼承的調度策略
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);  int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);  

在 pthread 庫中,提供了一個函數,用來設定被建立的線程的調度屬性:是從建立者線 程繼承調度屬性(調度策略和優先順序),還是從屬性對象設定調度屬性。該函數就是:

int pthread_attr_setinheritsched (pthread_attr_t *   attr, int    inherit) 當中,inherit 的值為下列值中的其一:enum{PTHREAD_INHERIT_SCHED, //線程調度屬性從建立者線程繼承 PTHREAD_EXPLICIT_SCHED //線程調度屬性設定為 attr 設定的屬性};

假設在建立新的線程時,調用該函數將參數設定為 PTHREAD_INHERIT_SCHED 時,那麼當改動進程的優先順序時。該進程中繼承這個優先順序而且還沒有改變其優先順序的所 有線程也將會跟著改變優先順序(也就是剛才那句話部分正確的原因)。


線程調度參數(實際上我們一般僅僅關心一個參數:線程的優先順序,默覺得0)
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);  //sched_param結構體  struct sched_param {      int sched_priority;     /* Scheduling priority */  };  
線程的並發層級
int pthread_setconcurrency(int new_level);  int pthread_getconcurrency(void); 

說明:並發層級僅在N:M執行緒模式中有效。設定並發層級,給核心一個提示:表示提供給定層級數量的核心線程來映射使用者線程是高效的(不過一個提示),默覺得0, 核心依照預設的方式進行並發。

我們來寫一個範例來運用:

/** 查看線程預設屬性 **/  void printThreadAttr()  {      pthread_attr_t attr;      pthread_attr_init(&attr);        int detachstate;      pthread_attr_getdetachstate(&attr, &detachstate);      cout << "detach-state: "           << (detachstate == PTHREAD_CREATE_JOINABLE ?

"PTHREAD_CREATE_JOINABLE" : "PTHREAD_CREATE_DETACHED") << endl; size_t size; pthread_attr_getstacksize(&attr, &size); cout << "stack-size: " << size << endl; pthread_attr_getguardsize(&attr, &size); cout << "guard-size: " << size << endl; int scope; pthread_attr_getscope(&attr, &scope); cout << "scope: " << (scope == PTHREAD_SCOPE_SYSTEM ? "PTHREAD_SCOPE_SYSTEM" : "PTHREAD_SCOPE_PROCESS") << endl; int policy; pthread_attr_getschedpolicy(&attr, &policy); cout << "policy: "; switch (policy) { case SCHED_FIFO: cout << "SCHED_FIFO"; break; case SCHED_RR: cout << "SCHED_RR"; break; case SCHED_OTHER: cout << "SCHED_OTHER"; break; default: break; } cout << endl; int inheritsched; pthread_attr_getinheritsched(&attr, &inheritsched); cout << "inheritsched: " << (inheritsched == PTHREAD_INHERIT_SCHED ?

"PTHREAD_INHERIT_SCHED" : "PTHREAD_INHERIT_SCHED") << endl; struct sched_param param; pthread_attr_getschedparam(&attr, ?m); cout << "scheduling priority: " << param.sched_priority << endl; cout << "concurrency: " << pthread_getconcurrency() << endl; pthread_attr_destroy(&attr); }


說明:

綁定屬性:

  Linux中採用“一對一”的線程機制。也就是一個使用者線程相應一個核心線程。

綁定屬性就是指一個使用者線程固定地分配給一個核心線程。由於CPU時間片的調度是面向核心線程(也就是輕量級進程)的,因此具有綁定屬性的線程能夠保證在須要的時候總有一個核心線程與之相應。而與之相應的非綁定屬性就是指使用者線程和核心線程的關係不是始終固定的,而是由系統來控制分配的。 

分離屬性:

  分離屬性是用來決定一個線程以什麼樣的方式來終止自己。在非分離情況下,當一個線程結束時,它所佔用的系統資源並沒有被釋放。也就是沒有真正的終止。

僅僅有當pthread_join()函數返回時,建立的線程才幹釋放自己佔用的系統資源。而在分離屬性情況下,一個線程結束時馬上釋放它所佔有的系統資源。這裡要注意的一點是,假設設定一個線程的分離屬性。而這個線程執行又非常快,那麼它非常可能在pthread_create()函數返回之前就終止了。它終止以後就可能將線程號和系統資源移交給其它的線程使用。



Linux多線程實踐(三)線程的基本屬性設定API

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.