<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Linux多線程開發(三)

      Linux多線程開發(三)

      線程概述

      線程概述

       

       線程和進程區別

       

       線程之間共享和非共享資源

       

       NPTL

       

      線程創建

       

       

      代碼

       1 /*
       2     一般情況下,main函數所在的線程我們稱之為主線程(main線程),其余創建的線程
       3     稱之為子線程。
       4     程序中默認只有一個進程,fork()函數調用,2進行
       5     程序中默認只有一個線程,pthread_create()函數調用,2個線程。
       6 
       7     #include <pthread.h>
       8     int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
       9     void *(*start_routine) (void *), void *arg);
      10 
      11         - 功能:創建一個子線程
      12         - 參數:
      13             - thread:傳出參數,線程創建成功后,子線程的線程ID被寫到該變量中。
      14             - attr : 設置線程的屬性,一般使用默認值,NULL
      15             - start_routine : 函數指針,這個函數是子線程需要處理的邏輯代碼
      16             - arg : 給第三個參數使用,傳參
      17         - 返回值:
      18             成功:0
      19             失敗:返回錯誤號。這個錯誤號和之前errno不太一樣。
      20             獲取錯誤號的信息:  char * strerror(int errnum);
      21 
      22 */
      23 #include <stdio.h>
      24 #include <pthread.h>
      25 #include <string.h>
      26 #include <unistd.h>
      27 
      28 void * callback(void * arg) {
      29     printf("child thread...\n");
      30     printf("arg value: %d\n", *(int *)arg);
      31     return NULL;
      32 }
      33 
      34 int main() {
      35 
      36     pthread_t tid;
      37 
      38     int num = 10;
      39 
      40     // 創建一個子線程
      41     int ret = pthread_create(&tid, NULL, callback, (void *)&num);
      42 
      43     if(ret != 0) {
      44         char * errstr = strerror(ret);
      45         printf("error : %s\n", errstr);
      46     } 
      47 
      48     for(int i = 0; i < 5; i++) {
      49         printf("%d\n", i);
      50     }
      51 
      52     sleep(1);
      53 
      54     return 0;   // exit(0);
      55 }

       

      終止線程

       

       

      代碼

       1 /*
       2 
       3     #include <pthread.h>
       4     void pthread_exit(void *retval);
       5         功能:終止一個線程,在哪個線程中調用,就表示終止哪個線程
       6         參數:
       7             retval:需要傳遞一個指針,作為一個返回值,可以在pthread_join()中獲取到。
       8 
       9     pthread_t pthread_self(void);
      10         功能:獲取當前的線程的線程ID
      11 
      12     int pthread_equal(pthread_t t1, pthread_t t2);
      13         功能:比較兩個線程ID是否相等
      14         不同的操作系統,pthread_t類型的實現不一樣,有的是無符號的長整型,有的
      15         是使用結構體去實現的。
      16 */
      17 #include <stdio.h>
      18 #include <pthread.h>
      19 #include <string.h>
      20 
      21 void * callback(void * arg) {
      22     printf("child thread id : %ld\n", pthread_self());
      23     return NULL;    // pthread_exit(NULL);
      24 } 
      25 
      26 int main() {
      27 
      28     // 創建一個子線程
      29     pthread_t tid;
      30     int ret = pthread_create(&tid, NULL, callback, NULL);
      31 
      32     if(ret != 0) {
      33         char * errstr = strerror(ret);
      34         printf("error : %s\n", errstr);
      35     }
      36 
      37     // 主線程
      38     for(int i = 0; i < 5; i++) {
      39         printf("%d\n", i);
      40     }
      41 
      42     printf("tid : %ld, main thread id : %ld\n", tid ,pthread_self());
      43 
      44     // 讓主線程退出,當主線程退出時,不會影響其他正常運行的線程。
      45     pthread_exit(NULL);
      46 
      47     printf("main thread exit\n");
      48 
      49     return 0;   // exit(0);
      50 }

       

      pthread_self當前進程的id

       

      連接已終止的線程

       

       

      代碼

       1 /*
       2     #include <pthread.h>
       3     int pthread_join(pthread_t thread, void **retval);
       4         - 功能:和一個已經終止的線程進行連接
       5                 回收子線程的資源
       6                 這個函數是阻塞函數,調用一次只能回收一個子線程
       7                 一般在主線程中使用
       8         - 參數:
       9             - thread:需要回收的子線程的ID
      10             - retval: 接收子線程退出時的返回值
      11         - 返回值:
      12             0 : 成功
      13             非0 : 失敗,返回的錯誤號
      14 */
      15 
      16 #include <stdio.h>
      17 #include <pthread.h>
      18 #include <string.h>
      19 #include <unistd.h>
      20 
      21 int value = 10;
      22 
      23 void * callback(void * arg) {
      24     printf("child thread id : %ld\n", pthread_self());
      25     // sleep(3);
      26     // return NULL; 
      27     // int value = 10; // 局部變量
      28     pthread_exit((void *)&value);   // return (void *)&value;
      29 } 
      30 
      31 int main() {
      32 
      33     // 創建一個子線程
      34     pthread_t tid;
      35     int ret = pthread_create(&tid, NULL, callback, NULL);
      36 
      37     if(ret != 0) {
      38         char * errstr = strerror(ret);
      39         printf("error : %s\n", errstr);
      40     }
      41 
      42     // 主線程
      43     for(int i = 0; i < 5; i++) {
      44         printf("%d\n", i);
      45     }
      46 
      47     printf("tid : %ld, main thread id : %ld\n", tid ,pthread_self());
      48 
      49     // 主線程調用pthread_join()回收子線程的資源
      50     int * thread_retval;
      51     ret = pthread_join(tid, (void **)&thread_retval);
      52 
      53     if(ret != 0) {
      54         char * errstr = strerror(ret);
      55         printf("error : %s\n", errstr);
      56     }
      57 
      58     printf("exit data : %d\n", *thread_retval);
      59 
      60     printf("回收子線程資源成功!\n");
      61 
      62     // 讓主線程退出,當主線程退出時,不會影響其他正常運行的線程。
      63     pthread_exit(NULL);
      64 
      65     return 0; 
      66 }

       

      線程的分離

      代碼

       1 /*
       2     #include <pthread.h>
       3     int pthread_detach(pthread_t thread);
       4         - 功能:分離一個線程。被分離的線程在終止的時候,會自動釋放資源返回給系統。
       5           1.不能多次分離,會產生不可預料的行為。
       6           2.不能去連接一個已經分離的線程,會報錯。
       7         - 參數:需要分離的線程的ID
       8         - 返回值:
       9             成功:0
      10             失敗:返回錯誤號
      11 */
      12 #include <stdio.h>
      13 #include <pthread.h>
      14 #include <string.h>
      15 #include <unistd.h>
      16 
      17 void * callback(void * arg) {
      18     printf("chid thread id : %ld\n", pthread_self());
      19     return NULL;
      20 }
      21 
      22 int main() {
      23 
      24     // 創建一個子線程
      25     pthread_t tid;
      26 
      27     int ret = pthread_create(&tid, NULL, callback, NULL);
      28     if(ret != 0) {
      29         char * errstr = strerror(ret);
      30         printf("error1 : %s\n", errstr);
      31     }
      32 
      33     // 輸出主線程和子線程的id
      34     printf("tid : %ld, main thread id : %ld\n", tid, pthread_self());
      35 
      36     // 設置子線程分離,子線程分離后,子線程結束時對應的資源就不需要主線程釋放
      37     ret = pthread_detach(tid);
      38     if(ret != 0) {
      39         char * errstr = strerror(ret);
      40         printf("error2 : %s\n", errstr);
      41     }
      42 
      43     // 設置分離后,對分離的子線程進行連接 pthread_join()
      44     // ret = pthread_join(tid, NULL);
      45     // if(ret != 0) {
      46     //     char * errstr = strerror(ret);
      47     //     printf("error3 : %s\n", errstr);
      48     // }
      49 
      50     pthread_exit(NULL);
      51 
      52     return 0;
      53 }

       

      線程操作

       

       

      線程取消

      pthread_cancel:取消線程或者是讓線程終止

      是遇到終止點才取消,沒遇到終止點不取消。

       

      代碼

       1 /*
       2     #include <pthread.h>
       3     int pthread_cancel(pthread_t thread);
       4         - 功能:取消線程(讓線程終止)
       5             取消某個線程,可以終止某個線程的運行,
       6             但是并不是立馬終止,而是當子線程執行到一個取消點,線程才會終止。
       7             取消點:系統規定好的一些系統調用,我們可以粗略的理解為從用戶區到內核區的切換,這個位置稱之為取消點。
       8 */
       9 
      10 #include <stdio.h>
      11 #include <pthread.h>
      12 #include <string.h>
      13 #include <unistd.h>
      14 
      15 void * callback(void * arg) {
      16     printf("chid thread id : %ld\n", pthread_self());
      17     for(int i = 0; i < 5; i++) {
      18         printf("child : %d\n", i);
      19     }
      20     return NULL;
      21 }
      22 
      23 int main() {
      24     
      25     // 創建一個子線程
      26     pthread_t tid;
      27 
      28     int ret = pthread_create(&tid, NULL, callback, NULL);
      29     if(ret != 0) {
      30         char * errstr = strerror(ret);
      31         printf("error1 : %s\n", errstr);
      32     }
      33 
      34     // 取消線程
      35     pthread_cancel(tid);
      36 
      37     for(int i = 0; i < 5; i++) {
      38         printf("%d\n", i);
      39     }
      40 
      41     // 輸出主線程和子線程的id
      42     printf("tid : %ld, main thread id : %ld\n", tid, pthread_self());
      43 
      44     
      45     pthread_exit(NULL);
      46 
      47     return 0;
      48 }

       

      線程屬性

       

       

       

       

      代碼

       1 /*
       2     int pthread_attr_init(pthread_attr_t *attr);
       3         - 初始化線程屬性變量
       4 
       5     int pthread_attr_destroy(pthread_attr_t *attr);
       6         - 釋放線程屬性的資源
       7 
       8     int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
       9         - 獲取線程分離的狀態屬性
      10 
      11     int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
      12         - 設置線程分離的狀態屬性
      13 */     
      14 
      15 #include <stdio.h>
      16 #include <pthread.h>
      17 #include <string.h>
      18 #include <unistd.h>
      19 
      20 void * callback(void * arg) {
      21     printf("chid thread id : %ld\n", pthread_self());
      22     return NULL;
      23 }
      24 
      25 int main() {
      26 
      27     // 創建一個線程屬性變量
      28     pthread_attr_t attr;
      29     // 初始化屬性變量
      30     pthread_attr_init(&attr);
      31 
      32     // 設置屬性
      33     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      34 
      35     // 創建一個子線程
      36     pthread_t tid;
      37 
      38     int ret = pthread_create(&tid, &attr, callback, NULL);
      39     if(ret != 0) {
      40         char * errstr = strerror(ret);
      41         printf("error1 : %s\n", errstr);
      42     }
      43 
      44     // 獲取線程的棧的大小
      45     size_t size;
      46     pthread_attr_getstacksize(&attr, &size);
      47     printf("thread stack size : %ld\n", size);
      48 
      49     // 輸出主線程和子線程的id
      50     printf("tid : %ld, main thread id : %ld\n", tid, pthread_self());
      51 
      52     // 釋放線程屬性資源
      53     pthread_attr_destroy(&attr);
      54 
      55     pthread_exit(NULL);
      56 
      57     return 0;
      58 }

       

      線程同步

       

       

       

       

       

       

      代碼

       1 /*
       2     使用多線程實現買票的案例。
       3     有3個窗口,一共是100張票。
       4 */
       5 
       6 #include <stdio.h>
       7 #include <pthread.h>
       8 #include <unistd.h>
       9 
      10 // 全局變量,所有的線程都共享這一份資源。
      11 int tickets = 100;
      12 
      13 void * sellticket(void * arg) {
      14     // 賣票
      15     while(tickets > 0) {
      16         usleep(6000);
      17         printf("%ld 正在賣第 %d 張門票\n", pthread_self(), tickets);
      18         tickets--;
      19     }
      20     return NULL;
      21 }
      22 
      23 int main() {
      24 
      25     // 創建3個子線程
      26     pthread_t tid1, tid2, tid3;
      27     pthread_create(&tid1, NULL, sellticket, NULL);
      28     pthread_create(&tid2, NULL, sellticket, NULL);
      29     pthread_create(&tid3, NULL, sellticket, NULL);
      30 
      31     // 回收子線程的資源,阻塞
      32     pthread_join(tid1, NULL);
      33     pthread_join(tid2, NULL);
      34     pthread_join(tid3, NULL);
      35 
      36     // 設置線程分離。
      37     // pthread_detach(tid1);
      38     // pthread_detach(tid2);
      39     // pthread_detach(tid3);
      40 
      41     pthread_exit(NULL); // 退出主線程
      42 
      43     return 0;
      44 }

       

      注意:分離后join,會報錯。

      usleep(3000):3000微秒。

       

      互斥鎖

      互斥量

       

       

       

       

       

       

       

      代碼

       1 /*
       2     互斥量的類型 pthread_mutex_t
       3     int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
       4         - 初始化互斥量
       5         - 參數 :
       6             - mutex : 需要初始化的互斥量變量
       7             - attr : 互斥量相關的屬性,NULL
       8         - restrict : C語言的修飾符,被修飾的指針,不能由另外的一個指針進行操作。
       9             pthread_mutex_t *restrict mutex = xxx;
      10             pthread_mutex_t * mutex1 = mutex;
      11 
      12     int pthread_mutex_destroy(pthread_mutex_t *mutex);
      13         - 釋放互斥量的資源
      14 
      15     int pthread_mutex_lock(pthread_mutex_t *mutex);
      16         - 加鎖,阻塞的,如果有一個線程加鎖了,那么其他的線程只能阻塞等待
      17 
      18     int pthread_mutex_trylock(pthread_mutex_t *mutex);
      19         - 嘗試加鎖,如果加鎖失敗,不會阻塞,會直接返回。
      20 
      21     int pthread_mutex_unlock(pthread_mutex_t *mutex);
      22         - 解鎖
      23 */
      24 #include <stdio.h>
      25 #include <pthread.h>
      26 #include <unistd.h>
      27 
      28 // 全局變量,所有的線程都共享這一份資源。
      29 int tickets = 1000;
      30 
      31 // 創建一個互斥量
      32 pthread_mutex_t mutex;
      33 
      34 void * sellticket(void * arg) {
      35 
      36     // 賣票
      37     while(1) {
      38 
      39         // 加鎖
      40         pthread_mutex_lock(&mutex);
      41 
      42         if(tickets > 0) {
      43             usleep(6000);
      44             printf("%ld 正在賣第 %d 張門票\n", pthread_self(), tickets);
      45             tickets--;
      46         }else {
      47             // 解鎖
      48             pthread_mutex_unlock(&mutex);
      49             break;
      50         }
      51 
      52         // 解鎖
      53         pthread_mutex_unlock(&mutex);
      54     }
      55 
      56     
      57 
      58     return NULL;
      59 }
      60 
      61 int main() {
      62 
      63     // 初始化互斥量
      64     pthread_mutex_init(&mutex, NULL);
      65 
      66     // 創建3個子線程
      67     pthread_t tid1, tid2, tid3;
      68     pthread_create(&tid1, NULL, sellticket, NULL);
      69     pthread_create(&tid2, NULL, sellticket, NULL);
      70     pthread_create(&tid3, NULL, sellticket, NULL);
      71 
      72     // 回收子線程的資源,阻塞
      73     pthread_join(tid1, NULL);
      74     pthread_join(tid2, NULL);
      75     pthread_join(tid3, NULL);
      76 
      77     pthread_exit(NULL); // 退出主線程
      78 
      79     // 釋放互斥量資源
      80     pthread_mutex_destroy(&mutex);
      81 
      82     return 0;
      83 }

       

      死鎖

      死鎖

       

       

      代碼

      deadlock.c

       1 #include <stdio.h>
       2 #include <pthread.h>
       3 #include <unistd.h>
       4 
       5 // 全局變量,所有的線程都共享這一份資源。
       6 int tickets = 1000;
       7 
       8 // 創建一個互斥量
       9 pthread_mutex_t mutex;
      10 
      11 void * sellticket(void * arg) {
      12 
      13     // 賣票
      14     while(1) {
      15 
      16         // 加鎖
      17         pthread_mutex_lock(&mutex);
      18         pthread_mutex_lock(&mutex);
      19 
      20         if(tickets > 0) {
      21             usleep(6000);
      22             printf("%ld 正在賣第 %d 張門票\n", pthread_self(), tickets);
      23             tickets--;
      24         }else {
      25             // 解鎖
      26             pthread_mutex_unlock(&mutex);
      27             break;
      28         }
      29 
      30         // 解鎖
      31         pthread_mutex_unlock(&mutex);
      32         pthread_mutex_unlock(&mutex);
      33     }
      34 
      35     return NULL;
      36 }
      37 
      38 int main() {
      39 
      40     // 初始化互斥量
      41     pthread_mutex_init(&mutex, NULL);
      42 
      43     // 創建3個子線程
      44     pthread_t tid1, tid2, tid3;
      45     pthread_create(&tid1, NULL, sellticket, NULL);
      46     pthread_create(&tid2, NULL, sellticket, NULL);
      47     pthread_create(&tid3, NULL, sellticket, NULL);
      48 
      49     // 回收子線程的資源,阻塞
      50     pthread_join(tid1, NULL);
      51     pthread_join(tid2, NULL);
      52     pthread_join(tid3, NULL);
      53 
      54     pthread_exit(NULL); // 退出主線程
      55 
      56     // 釋放互斥量資源
      57     pthread_mutex_destroy(&mutex);
      58 
      59     return 0;
      60 }

       

      deadlock1.c(多線程多鎖造成的死鎖場景)

       1 #include <stdio.h>
       2 #include <pthread.h>
       3 #include <unistd.h>
       4 
       5 // 創建2個互斥量
       6 pthread_mutex_t mutex1, mutex2;
       7 
       8 void * workA(void * arg) {
       9 
      10     pthread_mutex_lock(&mutex1);
      11     sleep(1);
      12     pthread_mutex_lock(&mutex2);
      13 
      14     printf("workA....\n");
      15 
      16     pthread_mutex_unlock(&mutex2);
      17     pthread_mutex_unlock(&mutex1);
      18     return NULL;
      19 }
      20 
      21 
      22 void * workB(void * arg) {
      23     pthread_mutex_lock(&mutex2);
      24     sleep(1);
      25     pthread_mutex_lock(&mutex1);
      26 
      27     printf("workB....\n");
      28 
      29     pthread_mutex_unlock(&mutex1);
      30     pthread_mutex_unlock(&mutex2);
      31 
      32     return NULL;
      33 }
      34 
      35 int main() {
      36 
      37     // 初始化互斥量
      38     pthread_mutex_init(&mutex1, NULL);
      39     pthread_mutex_init(&mutex2, NULL);
      40 
      41     // 創建2個子線程
      42     pthread_t tid1, tid2;
      43     pthread_create(&tid1, NULL, workA, NULL);
      44     pthread_create(&tid2, NULL, workB, NULL);
      45 
      46     // 回收子線程資源
      47     pthread_join(tid1, NULL);
      48     pthread_join(tid2, NULL);
      49 
      50     // 釋放互斥量資源
      51     pthread_mutex_destroy(&mutex1);
      52     pthread_mutex_destroy(&mutex2);
      53 
      54     return 0;
      55 }

       

      讀寫鎖

       

       

       

       

      代碼

       1 /*
       2     讀寫鎖的類型 pthread_rwlock_t
       3     int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
       4     int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
       5     int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
       6     int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
       7     int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
       8     int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
       9     int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
      10 
      11     案例:8個線程操作同一個全局變量。
      12     3個線程不定時寫這個全局變量,5個線程不定時的讀這個全局變量
      13 */
      14 
      15 #include <stdio.h>
      16 #include <pthread.h>
      17 #include <unistd.h>
      18 
      19 // 創建一個共享數據
      20 int num = 1;
      21 // pthread_mutex_t mutex;
      22 pthread_rwlock_t rwlock;
      23 
      24 void * writeNum(void * arg) {
      25 
      26     while(1) {
      27         pthread_rwlock_wrlock(&rwlock);
      28         num++;
      29         printf("++write, tid : %ld, num : %d\n", pthread_self(), num);
      30         pthread_rwlock_unlock(&rwlock);
      31         usleep(100);
      32     }
      33 
      34     return NULL;
      35 }
      36 
      37 void * readNum(void * arg) {
      38 
      39     while(1) {
      40         pthread_rwlock_rdlock(&rwlock);
      41         printf("===read, tid : %ld, num : %d\n", pthread_self(), num);
      42         pthread_rwlock_unlock(&rwlock);
      43         usleep(100);
      44     }
      45 
      46     return NULL;
      47 }
      48 
      49 int main() {
      50 
      51    pthread_rwlock_init(&rwlock, NULL);
      52 
      53     // 創建3個寫線程,5個讀線程
      54     pthread_t wtids[3], rtids[5];
      55     for(int i = 0; i < 3; i++) {
      56         pthread_create(&wtids[i], NULL, writeNum, NULL);
      57     }
      58 
      59     for(int i = 0; i < 5; i++) {
      60         pthread_create(&rtids[i], NULL, readNum, NULL);
      61     }
      62 
      63     // 設置線程分離
      64     for(int i = 0; i < 3; i++) {
      65        pthread_detach(wtids[i]);
      66     }
      67 
      68     for(int i = 0; i < 5; i++) {
      69          pthread_detach(rtids[i]);
      70     }
      71 
      72     pthread_exit(NULL);
      73 
      74     pthread_rwlock_destroy(&rwlock);
      75 
      76     return 0;
      77 }

       

      生產者和消費者模型

      該模型采用鏈表結構實現。

       

       

       代碼

       1 /*
       2     生產者消費者模型(粗略的版本)
       3 */
       4 #include <stdio.h>
       5 #include <pthread.h>
       6 #include <stdlib.h>
       7 #include <unistd.h>
       8 
       9 // 創建一個互斥量
      10 pthread_mutex_t mutex;
      11 
      12 struct Node{
      13     int num;
      14     struct Node *next;
      15 };
      16 
      17 // 頭結點
      18 struct Node * head = NULL;
      19 
      20 void * producer(void * arg) {
      21 
      22     // 不斷的創建新的節點,添加到鏈表中
      23     while(1) {
      24         pthread_mutex_lock(&mutex);
      25         struct Node * newNode = (struct Node *)malloc(sizeof(struct Node));
      26         newNode->next = head;
      27         head = newNode;
      28         newNode->num = rand() % 1000;
      29         printf("add node, num : %d, tid : %ld\n", newNode->num, pthread_self());
      30         pthread_mutex_unlock(&mutex);
      31         usleep(100);
      32     }
      33 
      34     return NULL;
      35 }
      36 
      37 void * customer(void * arg) {
      38 
      39     while(1) {
      40         pthread_mutex_lock(&mutex);
      41         // 保存頭結點的指針
      42         struct Node * tmp = head;
      43 
      44         // 判斷是否有數據
      45         if(head != NULL) {
      46             // 有數據
      47             head = head->next;
      48             printf("del node, num : %d, tid : %ld\n", tmp->num, pthread_self());
      49             free(tmp);
      50             pthread_mutex_unlock(&mutex);
      51             usleep(100);
      52         } else {
      53             // 沒有數據
      54             pthread_mutex_unlock(&mutex);
      55         }
      56     }
      57     return  NULL;
      58 }
      59 
      60 int main() {
      61 
      62     pthread_mutex_init(&mutex, NULL);
      63 
      64     // 創建5個生產者線程,和5個消費者線程
      65     pthread_t ptids[5], ctids[5];
      66 
      67     for(int i = 0; i < 5; i++) {
      68         pthread_create(&ptids[i], NULL, producer, NULL);
      69         pthread_create(&ctids[i], NULL, customer, NULL);
      70     }
      71 
      72     for(int i = 0; i < 5; i++) {
      73         pthread_detach(ptids[i]);
      74         pthread_detach(ctids[i]);
      75     }
      76 
      77     while(1) {
      78         sleep(10);
      79     }
      80 
      81     pthread_mutex_destroy(&mutex);
      82 
      83     pthread_exit(NULL);
      84 
      85     return 0;
      86 }

       

      條件變量

       

       注意:解決線程同步的方法有互斥鎖和讀寫鎖,條件變量不是鎖,條件變量不用來解決線程同步的問題。

       

       

      代碼

        1 /*
        2     條件變量的類型 pthread_cond_t
        3     int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
        4     int pthread_cond_destroy(pthread_cond_t *cond);
        5     int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
        6         - 等待,調用了該函數,線程會阻塞。
        7     int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
        8         - 等待多長時間,調用了這個函數,線程會阻塞,直到指定的時間結束。
        9     int pthread_cond_signal(pthread_cond_t *cond);
       10         - 喚醒一個或者多個等待的線程
       11     int pthread_cond_broadcast(pthread_cond_t *cond);
       12         - 喚醒所有的等待的線程
       13 */
       14 #include <stdio.h>
       15 #include <pthread.h>
       16 #include <stdlib.h>
       17 #include <unistd.h>
       18 
       19 // 創建一個互斥量
       20 pthread_mutex_t mutex;
       21 // 創建條件變量
       22 pthread_cond_t cond;
       23 
       24 struct Node{
       25     int num;
       26     struct Node *next;
       27 };
       28 
       29 // 頭結點
       30 struct Node * head = NULL;
       31 
       32 void * producer(void * arg) {
       33 
       34     // 不斷的創建新的節點,添加到鏈表中
       35     while(1) {
       36         pthread_mutex_lock(&mutex);
       37         struct Node * newNode = (struct Node *)malloc(sizeof(struct Node));
       38         newNode->next = head;
       39         head = newNode;
       40         newNode->num = rand() % 1000;
       41         printf("add node, num : %d, tid : %ld\n", newNode->num, pthread_self());
       42         
       43         // 只要生產了一個,就通知消費者消費
       44         pthread_cond_signal(&cond);
       45 
       46         pthread_mutex_unlock(&mutex);
       47         usleep(100);
       48     }
       49 
       50     return NULL;
       51 }
       52 
       53 void * customer(void * arg) {
       54 
       55     while(1) {
       56         pthread_mutex_lock(&mutex);
       57         // 保存頭結點的指針
       58         struct Node * tmp = head;
       59         // 判斷是否有數據
       60         if(head != NULL) {
       61             // 有數據
       62             head = head->next;
       63             printf("del node, num : %d, tid : %ld\n", tmp->num, pthread_self());
       64             free(tmp);
       65             pthread_mutex_unlock(&mutex);
       66             usleep(100);
       67         } else {
       68             // 沒有數據,需要等待
       69             // 當這個函數調用阻塞的時候,會對互斥鎖進行解鎖,當不阻塞的,繼續向下執行,會重新加鎖。
       70             pthread_cond_wait(&cond, &mutex);
       71             pthread_mutex_unlock(&mutex);
       72         }
       73     }
       74     return  NULL;
       75 }
       76 
       77 int main() {
       78 
       79     pthread_mutex_init(&mutex, NULL);
       80     pthread_cond_init(&cond, NULL);
       81 
       82     // 創建5個生產者線程,和5個消費者線程
       83     pthread_t ptids[5], ctids[5];
       84 
       85     for(int i = 0; i < 5; i++) {
       86         pthread_create(&ptids[i], NULL, producer, NULL);
       87         pthread_create(&ctids[i], NULL, customer, NULL);
       88     }
       89 
       90     for(int i = 0; i < 5; i++) {
       91         pthread_detach(ptids[i]);
       92         pthread_detach(ctids[i]);
       93     }
       94 
       95     while(1) {
       96         sleep(10);
       97     }
       98 
       99     pthread_mutex_destroy(&mutex);
      100     pthread_cond_destroy(&cond);
      101 
      102     pthread_exit(NULL);
      103 
      104     return 0;
      105 }

       

      信號量(信號燈)

      注意:單獨使用信號量不能讓線程安全,需要配合使用互斥鎖才能保證線程的安全。

      信號量的類型

       代碼

        1 /*
        2     信號量的類型 sem_t
        3     int sem_init(sem_t *sem, int pshared, unsigned int value);
        4         - 初始化信號量
        5         - 參數:
        6             - sem : 信號量變量的地址
        7             - pshared : 0 用在線程間 ,非0 用在進程間
        8             - value : 信號量中的值
        9 
       10     int sem_destroy(sem_t *sem);
       11         - 釋放資源
       12 
       13     int sem_wait(sem_t *sem);
       14         - 對信號量加鎖,調用一次對信號量的值-1,如果值為0,就阻塞
       15 
       16     int sem_trywait(sem_t *sem);
       17 
       18     int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
       19     int sem_post(sem_t *sem);
       20         - 對信號量解鎖,調用一次對信號量的值+1
       21 
       22     int sem_getvalue(sem_t *sem, int *sval);
       23 
       24     sem_t psem;
       25     sem_t csem;
       26     init(psem, 0, 8);
       27     init(csem, 0, 0);
       28 
       29     producer() {
       30         sem_wait(&psem);
       31         sem_post(&csem)
       32     }
       33 
       34     customer() {
       35         sem_wait(&csem);
       36         sem_post(&psem)
       37     }
       38 
       39 */
       40 
       41 #include <stdio.h>
       42 #include <pthread.h>
       43 #include <stdlib.h>
       44 #include <unistd.h>
       45 #include <semaphore.h>
       46 
       47 // 創建一個互斥量
       48 pthread_mutex_t mutex;
       49 // 創建兩個信號量
       50 sem_t psem;
       51 sem_t csem;
       52 
       53 struct Node{
       54     int num;
       55     struct Node *next;
       56 };
       57 
       58 // 頭結點
       59 struct Node * head = NULL;
       60 
       61 void * producer(void * arg) {
       62 
       63     // 不斷的創建新的節點,添加到鏈表中
       64     while(1) {
       65         sem_wait(&psem);
       66         pthread_mutex_lock(&mutex);
       67         struct Node * newNode = (struct Node *)malloc(sizeof(struct Node));
       68         newNode->next = head;
       69         head = newNode;
       70         newNode->num = rand() % 1000;
       71         printf("add node, num : %d, tid : %ld\n", newNode->num, pthread_self());
       72         pthread_mutex_unlock(&mutex);
       73         sem_post(&csem);
       74     }
       75 
       76     return NULL;
       77 }
       78 
       79 void * customer(void * arg) {
       80 
       81     while(1) {
       82         sem_wait(&csem);
       83         pthread_mutex_lock(&mutex);
       84         // 保存頭結點的指針
       85         struct Node * tmp = head;
       86         head = head->next;
       87         printf("del node, num : %d, tid : %ld\n", tmp->num, pthread_self());
       88         free(tmp);
       89         pthread_mutex_unlock(&mutex);
       90         sem_post(&psem);
       91        
       92     }
       93     return  NULL;
       94 }
       95 
       96 int main() {
       97 
       98     pthread_mutex_init(&mutex, NULL);
       99     sem_init(&psem, 0, 8);
      100     sem_init(&csem, 0, 0);
      101 
      102     // 創建5個生產者線程,和5個消費者線程
      103     pthread_t ptids[5], ctids[5];
      104 
      105     for(int i = 0; i < 5; i++) {
      106         pthread_create(&ptids[i], NULL, producer, NULL);
      107         pthread_create(&ctids[i], NULL, customer, NULL);
      108     }
      109 
      110     for(int i = 0; i < 5; i++) {
      111         pthread_detach(ptids[i]);
      112         pthread_detach(ctids[i]);
      113     }
      114 
      115     while(1) {
      116         sleep(10);
      117     }
      118 
      119     pthread_mutex_destroy(&mutex);
      120 
      121     pthread_exit(NULL);
      122 
      123     return 0;
      124 }

       

      posted @ 2022-02-28 22:05  白雪兒  Views(151)  Comments(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品午夜福利合集| 偷拍一区二区三区在线视频| 老司机亚洲精品一区二区| 国产精品伦人视频免费看| 欲香欲色天天天综合和网| 亚洲精品入口一区二区乱| 国产麻豆9l精品三级站| 九九热精品视频在线免费| 国产999久久高清免费观看| 欧美韩中文精品有码视频在线| 精品国产乱码久久久人妻| 乱码午夜-极品国产内射| 久久国内精品自在自线91| 国产97色在线 | 免费| 亚洲一级特黄大片在线播放 | 97欧美精品系列一区二区| 色九月亚洲综合网| 日本不卡片一区二区三区| 亚洲爆乳WWW无码专区| 欧美熟妇性XXXX欧美熟人多毛| 国内久久人妻风流av免费| 国产av一区二区午夜福利| 国产成人剧情AV麻豆果冻| 亚洲a∨无码无在线观看| 亚洲av乱码久久亚洲精品| 中文字幕国产精品av| 2020中文字字幕在线不卡| 不卡一区二区国产在线| 国产极品精品自在线不卡| 浴室人妻的情欲hd三级国产| 一 级做人爱全视频在线看| 午夜福利看片在线观看| 亚洲粉嫩av一区二区黑人| 亚洲第一福利网站在线| 麻豆麻豆麻豆麻豆麻豆麻豆| 野花香视频在线观看免费高清版| 国产精品一区二区久久精品| 原阳县| 午夜久久水蜜桃一区二区| 国产亚洲人成网站在线观看 | 日本三级理论久久人妻电影|