<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # 簡介 Linux下線程的屬性是可以根據實際項目需要,進行設置,之前我們討論的線程都是采用線程的默認屬性,默認屬性已經可以解決絕大多數開發時遇到的問題。 如我們對程序的性能提出更高的要求那么需要設置線程屬性,比如可以通過設置線程棧的大小來降低內存的使用,增加最大線程個數 ~~~ typedef struct { int etachstate; //線程的分離狀態 int schedpolicy; //線程調度策略 struct sched_param schedparam; //線程的調度參數 int inheritsched; //線程的繼承性 int scope; //線程的作用域 size_t guardsize; //線程棧末尾的警戒緩沖區大小 int stackaddr_set; //線程的棧設置 void* stackaddr; //線程棧的位置 size_t stacksize; //線程棧的大小 } pthread_attr_t; ~~~ 主要結構體成員: 1) 線程分離狀態 2) 線程棧大小(默認平均分配) 3) 線程棧警戒緩沖區大小(位于棧末尾) 4) 線程棧最低地址 屬性值不能直接設置,須使用相關函數進行操作,初始化的函數為pthread\_attr\_init,這個函數必須在pthread\_create函數之前調用。之后須用pthread\_attr\_destroy函數來釋放資源。 線程屬性主要包括如下屬性:作用域(scope)、棧尺寸(stack size)、棧地址(stack address)、優先級(priority)、分離的狀態(detached state)、調度策略和參數(scheduling policy and parameters)。默認的屬性為非綁定、非分離、缺省的堆棧、與父進程同樣級別的優先級。 # 線程屬性初始化和銷毀 ~~~ #include <pthread.h> ? int pthread_attr_init(pthread_attr_t *attr); 功能: 初始化線程屬性函數,注意:應先初始化線程屬性,再pthread_create創建線程 參數: attr:線程屬性結構體 返回值: 成功:0 失敗:錯誤號 ? int pthread_attr_destroy(pthread_attr_t *attr); 功能: 銷毀線程屬性所占用的資源函數 參數: attr:線程屬性結構體 返回值: 成功:0 失敗:錯誤號 ~~~ # 線程分離狀態 線程的分離狀態決定一個線程以什么樣的方式來終止自己。 * 非分離狀態:線程的默認屬性是非分離狀態,這種情況下,原有的線程等待創建的線程結束。只有當pthread\_join()函數返回時,創建的線程才算終止,才能釋放自己占用的系統資源。 * 分離狀態:分離線程沒有被其他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統資源。應該根據自己的需要,選擇適當的分離狀態。 ~~~ #include <pthread.h> ? int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); 功能:設置線程分離狀態 參數: attr:已初始化的線程屬性 detachstate: 分離狀態 PTHREAD_CREATE_DETACHED(分離線程) PTHREAD_CREATE_JOINABLE(非分離線程) 返回值: 成功:0 失敗:非0 ? int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); 功能:獲取線程分離狀態 參數: attr:已初始化的線程屬性 detachstate: 分離狀態 PTHREAD_CREATE_DETACHED(分離線程) PTHREAD _CREATE_JOINABLE(非分離線程) 返回值: 成功:0 失敗:非0 ~~~ 這里要注意的一點是,如果設置一個線程為分離線程,而這個線程運行又非常快,它很可能在pthread\_create函數返回之前就終止了,它終止以后就可能將線程號和系統資源移交給其他的線程使用,這樣調用pthread\_create的線程就得到了錯誤的線程號。 要避免這種情況可以采取一定的同步措施,最簡單的方法之一是可以在被創建的線程里調用pthread\_cond\_timedwait函數,讓這個線程等待一會兒,留出足夠的時間讓函數pthread\_create返回。 設置一段等待時間,是在多線程編程里常用的方法。但是注意不要使用諸如wait()之類的函數,它們是使整個進程睡眠,并不能解決線程同步的問題。 # 線程棧地址 POSIX.1定義了兩個常量來檢測系統是否支持棧屬性: * \_POSIX\_THREAD\_ATTR\_STACKADDR * \_POSIX\_THREAD\_ATTR\_STACKSIZE 也可以給sysconf函數傳遞來進行檢測: * \_SC\_THREAD\_ATTR\_STACKADDR * \_SC\_THREAD\_ATTR\_STACKSIZE 當進程棧地址空間不夠用時,指定新建線程使用由malloc分配的空間作為自己的棧空間。通過pthread\_attr\_setstack和pthread\_attr\_getstack兩個函數分別設置和獲取線程的棧地址。 ~~~ #include <pthread.h> ? int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); 功能:設置線程的棧地址 參數: attr:指向一個線程屬性的指針 stackaddr:內存首地址 stacksize:返回線程的堆棧大小 返回值: 成功:0 失敗:錯誤號 ? int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); 功能:獲取線程的棧地址 參數: attr:指向一個線程屬性的指針 stackaddr:返回獲取的棧地址 stacksize:返回獲取的棧大小 返回值: 成功:0 失敗:錯誤號 ~~~ # 線程棧大小 當系統中有很多線程時,可能需要減小每個線程棧的默認大小,防止進程的地址空間不夠用,當線程調用的函數會分配很大的局部變量或者函數調用層次很深時,可能需要增大線程棧的默認大小。 ~~~ #include <pthread.h> ? int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); 功能:設置線程的棧大小 參數: attr:指向一個線程屬性的指針 stacksize:線程的堆棧大小 返回值: 成功:0 失敗:錯誤號 ? int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); 功能:獲取線程的棧大小 參數: attr:指向一個線程屬性的指針 stacksize:返回線程的堆棧大小 返回值: 成功:0 失敗:錯誤號 ~~~ # 例子 ~~~ #define SIZE 0x100000 ? void *th_fun(void *arg) { while (1) { sleep(1); } } ? int main() { pthread_t tid; int err, detachstate, i = 1; ? pthread_attr_t attr; size_t stacksize; void *stackaddr; ? pthread_attr_init(&attr); //線程屬性初始化 pthread_attr_getstack(&attr, &stackaddr, &stacksize); //獲取線程的棧地址 pthread_attr_getdetachstate(&attr, &detachstate); //獲取線程分離狀態 ? if (detachstate == PTHREAD_CREATE_DETACHED) { printf("thread detached\n"); } else if (detachstate == PTHREAD_CREATE_JOINABLE) { printf("thread join\n"); } else { printf("thread unknown\n"); } pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //設置分離狀態 ? while (1) { stackaddr = malloc(SIZE); if (stackaddr == NULL) { perror("malloc"); exit(1); } ? stacksize = SIZE; pthread_attr_setstack(&attr, stackaddr, stacksize); //設置線程的棧地址 err = pthread_create(&tid, &attr, th_fun, NULL); //創建線程 if (err != 0) { printf("%s\n", strerror(err)); exit(1); } printf("%d\n", i++); } ? pthread_attr_destroy(&attr); //銷毀線程屬性所占用的資源函數 ? return 0; } ~~~ # 線程使用注意事項 1) 主線程退出其他線程不退出,主線程應調用pthread\_exit 2) 避免僵尸線程 a) pthread\_join b) pthread\_detach c) pthread\_create指定分離屬性 被join線程可能在join函數返回前就釋放完自己的所有內存資源,所以不應當返回被回收線程棧中的值; 3) malloc和mmap申請的內存可以被其他線程釋放 4) 應避免在多線程模型中調用fork,除非馬上exec,子進程中只有調用fork的線程存在,其他線程t在子進程中均pthread\_exit 5) 信號的復雜語義很難和多線程共存,應避免在多線程引入信號機制
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看