NDK学习笔记-多线程与生产消费模式
在做NDK開發的時候,很多情況下都是需要使用多線程的,一方面是提高程序運行效率,另一方面就是防止主線程阻塞
C的多線程
在C語言里,可以通過對于POSIX標準的運用,使得C語言執行多線程
提高程序的執行速度,以及對資源的合理利用
POSIX
POSIX原理
POSIX可以讓C語言實現多線程
其實現是是通過POSIX函數庫的調用實現的
POSIX函數庫可以看作是C語言庫函數的超集,對C語言盡行了增強
POSIX實現多線程
在C語言中調用POSIX庫函數可以實現多線程
在使用時,需要包含pthread.h頭文件
其步驟為:
- 創建線程ID,使用pthread_t創建線程ID
- 創建線程,使用pthread_create()創建線程
- 結束線程
線程依附于主線程,主線程結束,其子線程也就結束了
要使主線程等待子線程運行完畢,就需要使用pthread_join()函數
另外,在線程運行的時候可以結束線程,可以通過以下函數結束正在運行的線程
void pthread_exit(void *retval); int pthread_cancel(pthread_t thread);e.g.
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <pthread.h>void* thr_fun(void* arg){char* buf = (char*)arg;int i = 0;for(; i < 100; i++){printf("%s thread -%d-\n", buf, i);usleep(1000);}return "thread over\n"; }void main(){pthread_t tid; //創建線程IDpthread_create(&tid, NULL, thr_fun, "pass"); //創建線程并執行thr_fun函數int i = 0;for(; i < 100; i++){printf("main thread -%d-\n", i);usleep(1000);}void* rval;pthread_join(tid, &rval); //等待線程執行完畢printf("get from thread:%s", (char *)rval); }上述示例在加入usleep是為了主線程和子線程都能夠輸出
注意:在編譯有posix標準庫多線程的時候,應該添加-lpthread參數,否則會報錯
互斥鎖
為了線程的安全,給線程加上互斥鎖,這樣就可以確保線程安全
線程鎖的作用就是在一個線程進行訪問的時候,不允許其他線程進入
生產者與消費者
- 當存在多個線程對同一數據進行操作的時候,那么這個數據如果同時被多個線程操作,就會產生安全問題
- 比如線程A在訪問數據的時候丟失了CPU的控制權,此時線程B去操作了數據,那么線程A在重新得到CPU控制權的時候,其渠道的數據就是線程B操作過的數據,可能其數據并不是預期要取的值
- 面對這種情況,在設計模式里面就提出了生產者與消費者模型,這也是很常用的一種模型
單個生產者與單個消費者
這種情況下,只需要滿足生產者生產出來能及時被消費者消費
其生產者應該上鎖,生產,通知消費者,解鎖,然后按照這個流程不斷循環
消費者應該上鎖,消費,通知生產者,解鎖,然后按照這個流程不斷循環
全局變量
生產者方法
void* producer(void* arg){char *buf = (char *)arg;while(1){pthread_mutex_lock(&mutex); //上鎖ready++; //生產product_idx++;printf("%5d%s----%d\n", product_idx, buf, ready);pthread_cond_signal(&has_product); //通知消費者,會阻塞pthread_mutex_unlock(&mutex); //解鎖usleep(100 * 1000);} }消費者方法
void* consumer(void* arg){char *buf = (char *)arg;while(1){pthread_mutex_lock(&mutex); //上鎖while(ready == 0){pthread_cond_wait(&has_product,&mutex); //線程等待}ready--; //消費consumer_idx++;printf("%5d%s----%d\n", consumer_idx, buf, ready);pthread_mutex_unlock(&mutex); //解鎖usleep(100 * 1000);} }主方法
void main() {pthread_t pro_id, con_id;pthread_mutex_init(&mutex, NULL);pthread_cond_init(&has_product, NULL);pthread_create(&pro_id, NULL, producer, "producer");pthread_create(&con_id, NULL, consumer, "consumer");pthread_join(pro_id, NULL);pthread_join(con_id, NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&has_product); }以上方法就實現了線程的安全,在生產者有產品的時候通知消費者,消費者完成消費等待生產者
多個生產者與多個消費者
由于上面已經說明原理,這里直接貼出代碼
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <pthread.h>int ready = 0;#define CONSUMER_NUM 4 //消費者數量 #define PRODUCER_NUM 3 //生產者數量 pthread_t pids[CONSUMER_NUM + PRODUCER_NUM];pthread_mutex_t mutex; //互斥鎖 pthread_cond_t has_product; //條件變量void* producer(void* arg){int *num = (int *)arg;while(1){pthread_mutex_lock(&mutex); //上鎖ready++; //生產printf("%5d---product---%d\n", num, ready);pthread_cond_signal(&has_product); //通知消費者,會阻塞pthread_mutex_unlock(&mutex); //解鎖usleep(100 * 1000);} }void* consumer(void* arg){int *num = (int *)arg;while(1){pthread_mutex_lock(&mutex); //上鎖while(ready == 0){pthread_cond_wait(&has_product, &mutex); //線程等待}ready--; //消費printf("%5d---consumer---%d\n", num, ready);pthread_mutex_unlock(&mutex); //解鎖usleep(100 * 1000);} }void main() {pthread_mutex_init(&mutex, NULL);pthread_cond_init(&has_product, NULL);int i;for(i = 0; i < PRODUCER_NUM; i++){ //生產者線程pthread_create(&pids[i], NULL, producer, (void*)i);}for(i = 0; i < CONSUMER_NUM; i++){ //消費者線程pthread_create(&pids[PRODUCER_NUM + i], NULL, consumer, (void*)i);}sleep(10);for(i = 0; i < PRODUCER_NUM + CONSUMER_NUM; i++){pthread_join(pids[i], NULL);} pthread_mutex_destroy(&mutex);pthread_cond_destroy(&has_product); }轉載于:https://www.cnblogs.com/cj5785/p/10664651.html
總結
以上是生活随笔為你收集整理的NDK学习笔记-多线程与生产消费模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj3224
- 下一篇: 【面试】编译器为我们实现了几个类成员函数