日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POSIX线程

發布時間:2023/11/30 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POSIX线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

POSIX線程

標簽(空格分隔): Linux程序設計


什么是線程

線程是一個進程內部的一個控制序列。

當在進程中創建一個新線程時,新的執行線程將擁有自己的棧(因此也有自己的局部變量),但與它的創建者共享全局變量、文件描述符、信號處理函數和當前目錄狀態。

線程的優點:

  • 讓程序看起來好像是在做兩件事情;
  • 一個混雜著輸入、計算和輸出的應用程序,可以將這幾個部分分離成3個線程來執行,從而改善程序執行的性能;
  • 一般而言,線程之間的切換需要操作系統做的工作比進程之間的切換少的多,因此多個線程對資源的需求要遠少于多個進程。
  • 線程創建相關函數

    #include<pthread.h>//創建線程 int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); //thread: 指向pthread_t類型的指針,用來引用該新線程; //attr: 用于設置線程的屬性,一般為NULL; //第3,4個參數為線程將要啟動執行的函數,以及傳遞給該函數的參數 //返回:調用成功返回0,失敗則返回錯誤代碼//線程等待函數 int pthread_join(pthread_t th, void **thread_return); //th: 指定將要等待的線程 //thread_return: 指向線程返回值的指針(的指針)。 //返回:成功返回0,失敗則返回錯誤代碼//線程終止函數 void pthread_exit(void *retval); //retval: 指向線程返回值的指針(pthread_join可以獲取該指針)

    示例:

    #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<pthread.h>void *thread_function(void *arg); char msg[] = "Hello World";int main() {int res;pthread_t a_thread;void *thread_result;res = pthread_create(&a_thread, NULL, thread_function, (void *)msg);if(res != 0){perror("Thread creation failed.");exit(EXIT_FAILURE);}printf("Waiting for thread to finish...\n");res = pthread_join(a_thread, &thread_result);if(res != 0){perror("Thread join failed.");exit(EXIT_FAILURE);}printf("Thread joined, it returned %s\n", (char *)thread_result);printf("Message is now %s\n", msg);exit(EXIT_SUCCESS); }void *thread_function(void *arg) {printf("Thread function is runing. Argument was %s\n",(char *)arg);sleep(3);strcpy(msg,"Bye!");pthread_exit("Thank you for the CPU time."); }

    線程同步

    互斥量mutex

    參考:https://docs.oracle.com/cd/E19253-01/819-7051/sync-12/index.html

    #include<pthread.h>int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); //mutex: 事先聲明過的pthread_mutex_t對象的指針 //mutexattr: 設置互斥量的屬性,默認為fast。該參數一般置為NULL //返回: 成功返回0,失敗則返回錯誤代碼//加鎖 int pthread_mutex_lock(pthread_mutex_t *mutex);//解鎖 int pthread_mutex_unlock(pthread_mutex_t *mutex);//銷毀 int pthread_mutex_destroy(pthread_mutex_t *mutex);

    示例:

    #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <pthread.h>void *thread_function(void *arg); pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */#define WORK_SIZE 1024 char work_area[WORK_SIZE]; int time_to_exit = 0;int main() {int res;pthread_t a_thread;void *thread_result;res = pthread_mutex_init(&work_mutex, NULL);if (res != 0) {perror("Mutex initialization failed");exit(EXIT_FAILURE);}res = pthread_create(&a_thread, NULL, thread_function, NULL);if (res != 0) {perror("Thread creation failed");exit(EXIT_FAILURE);}pthread_mutex_lock(&work_mutex);printf("Input some text. Enter 'end' to finish\n");while(!time_to_exit) {fgets(work_area, WORK_SIZE, stdin);pthread_mutex_unlock(&work_mutex);while(1) {pthread_mutex_lock(&work_mutex);if (work_area[0] != '\0') {pthread_mutex_unlock(&work_mutex);sleep(1);}else {break;}}}pthread_mutex_unlock(&work_mutex);printf("\nWaiting for thread to finish...\n");res = pthread_join(a_thread, &thread_result);if (res != 0) {perror("Thread join failed");exit(EXIT_FAILURE);}printf("Thread joined\n");pthread_mutex_destroy(&work_mutex);exit(EXIT_SUCCESS); }void *thread_function(void *arg) {sleep(1);pthread_mutex_lock(&work_mutex);while(strncmp("end", work_area, 3) != 0) {printf("You input %d characters\n", strlen(work_area) -1);work_area[0] = '\0';pthread_mutex_unlock(&work_mutex);sleep(1);pthread_mutex_lock(&work_mutex);while (work_area[0] == '\0' ) {pthread_mutex_unlock(&work_mutex);sleep(1);pthread_mutex_lock(&work_mutex);}}time_to_exit = 1;work_area[0] = '\0';pthread_mutex_unlock(&work_mutex);pthread_exit(0); }

    條件變量

    參考:
    IBM Knowledge Center: 使用條件變量
    知乎:條件變量之稀里糊涂的鎖
    有了互斥鎖,為什么還要條件變量?
    linux多線程使用pthread_cond條件變量

    條件變量(cond)是在多線程程序中用來實現"等待->喚醒"邏輯常用的方法。條件變量利用線程間共享的全局變量進行同步的一種機制。

    條件變量必須始終與互斥對象一起使用。主要為了防止競爭死鎖(防止pthread_cond_signal在pthread_cond_wait之前調用,導致線程永久等待)。

    保護條件的互斥對象必須在等待條件前被鎖定。線程可等待通過調用 pthread_cond_wait 或者 pthread_cond_timedwait 子例程發信號的條件。子例程以不可分割的方式解鎖互斥對象并阻塞調用線程,直到條件收到信號。當調用返回時,互斥對象再次被鎖定。

    pthread_cond_wait 子例程無限期阻塞線程。如果條件永不收到信號,那么線程將永不喚醒。因為 pthread_cond_wait 子例程提供取消點,所以如果啟用可取消,那么退出此死鎖的唯一方法是取消被阻塞的線程。

    pthread_cond_wait函數的返回并不意味著條件的值一定發生了變化,必須重新檢查條件的值。

    pthread_cond_signal 子例程至少喚醒一個當前在指定條件上被阻塞的線程。根據調度策略選擇被喚醒的線程。

    pthread_cond_broadcast 子例程喚醒當前被阻塞在指定的條件下的每一個線程。但是,線程能夠在調用子例程返回后即開始等待相同的條件。

    #include <pthread.h>//定義條件變量 pthread_cond_t cond;//初始化條件變量 int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr) //cond:事先定義好的條件變量指針 //attr:事先定義好的條件變量屬性(默認NULL)//等待 1)調用時:解除鎖,等待條件變量,然后阻塞 2)返回時:收到信號,再次鎖定 int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex); //cond:初始化后的條件變量 //mutex:綁定的互斥量//定時等待 int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *timeout);//發送信號 int pthread_cond_signal (pthread_cond_t *condition);//銷毀條件變量 int pthread_cond_destroy (pthread_cond_t *cond)

    示例:

    #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<pthread.h> #include<stdbool.h>void *thread_function1(void *arg); void *thread_function2(void *arg); pthread_mutex_t count_mutex; pthread_cond_t count_threshold_cv; bool ready = false; char msg1[] = "this is thread 1"; char msg2[] = "this is thread 2"; int main() {pthread_t thread1;pthread_t thread2;pthread_mutex_init(&count_mutex, NULL);pthread_cond_init (&count_threshold_cv, NULL);pthread_create(&thread1, NULL, thread_function1, (void *)msg1);pthread_create(&thread2, NULL, thread_function2, (void *)msg2);printf("waiting for thread to finish...\n");pthread_join(thread1, NULL);pthread_join(thread2, NULL);pthread_mutex_destroy(&count_mutex);pthread_cond_destroy(&count_threshold_cv);return 0; }void *thread_function1(void *arg) {printf("Tips:%s\n", (char *)arg);pthread_mutex_lock(&count_mutex);while (false == ready){pthread_cond_wait(&count_threshold_cv, &count_mutex);printf("thread1 in pthread_cond_wait\n");}if(true == ready)printf("now ready = true in thread1.\n");pthread_mutex_unlock(&count_mutex);pthread_exit(0); }void *thread_function2(void *arg) {sleep(3);printf("Tips:%s\n", (char *)arg);pthread_mutex_lock(&count_mutex);ready = true;printf("thread2 set ready = true\n");pthread_mutex_unlock(&count_mutex);pthread_cond_signal(&count_threshold_cv);pthread_exit(0); }

    判斷條件狀態的時候ready==false放在了while循環中,而不是if中,這是因為pthread_cond_wait()阻塞在條件變量上的時候,即使其他的線程沒有就該條件變量發出通知(pthread_cond_signal()/pthread_cond_broadcast()),條件變量也有可能會自己醒來(pthread_cond_wait()函數返回),因此需要重新檢查一下共享變量上的條件成不成立,確保條件變量是真的收到了通知,否則繼續阻塞等待。關于虛假喚醒的相關介紹,可以戳這里查看維基百科下面的幾個引用:https://en.wikipedia.org/wiki/Spurious_wakeup。

    轉載于:https://www.cnblogs.com/wuxubj/p/10805386.html

    總結

    以上是生活随笔為你收集整理的POSIX线程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。