一、C/C++多線程操作說明
C/C++多線程基本操作如下:
1. 線程的建立結束
2. 線程的互斥和同步
3. 使用信號量控制線程
4. 線程的基本屬性配置
在C/C++代碼編寫時,使用多線程機制,首先需要做的事情就是聲明引用,具體如下:
#include "pthread.h"
二、線程基本操作方法
基本線程操作:
1. pthread_create():創建線程開始運行相關線程函數,運行結束則線程退出
2. pthread_eixt():因為exit()是用來結束進程的,所以則需要使用特定結束線程的函數
3. pthread_join():掛起當前線程,用於阻塞式地等待線程結束,如果線程已結束則立即返回,0=成功
4. pthread_cancel():發送終止信號給thread線程,成功返回0,但是成功並不意味着thread會終止
5. pthread_testcancel():在不包含取消點,但是又需要取消點的地方創建一個取消點,以便在一個沒有包含取消點的執行代碼線程中響應取消請求.
6. pthread_setcancelstate():設置本線程對cancle線程的反應
7. pthread_setcanceltype():設置取消狀態 繼續運行至下一個取消點再退出或者是立即執行取消動作
8. pthread_setcancel():設置取消狀態
三、線程互斥與同步機制
基本的互斥與同步的操作方法:
1. pthread_mutex_init():互斥鎖的初始化
2. pthread_mutex_lock():鎖定互斥鎖,如果嘗試鎖定已經被上鎖的互斥鎖則阻塞至可用為止
3. pthread_mutex_trylock():非阻塞的鎖定互斥鎖
4. pthread_mutex_unlock():釋放互斥鎖
5. pthread_mutex_destory():互斥鎖銷毀函數
四、多線程實踐
1. 基本的線程及建立運行
下面的代碼是C/C++開發的基本的線程的運行,使用的就是最基本的pthread.h:
/* thread.c */ #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define THREAD_NUMBER 3 /*線程數*/ #define REPEAT_NUMBER 5 /*每個線程中的小任務數*/ #define DELAY_TIME_LEVELS 10.0 /*小任務之間的最大時間間隔*/ // void *thrd_func(void *arg) { /* 線程函數例程 */ int thrd_num = (int)arg; int delay_time = 0; int count = 0; printf("Thread %d is starting\n", thrd_num); for (count = 0; count < REPEAT_NUMBER; count++) { delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1; sleep(delay_time); printf("\tThread %d: job %d delay = %d\n", thrd_num, count, delay_time); } printf("Thread %d finished\n", thrd_num); pthread_exit(NULL); } int main(void) { pthread_t thread[THREAD_NUMBER]; int no = 0, res; void * thrd_ret; srand(time(NULL)); for (no = 0; no < THREAD_NUMBER; no++) { /* 創建多線程 */ res = pthread_create(&thread[no], NULL, thrd_func, (void*)no); if (res != 0) { printf("Create thread %d failed\n", no); exit(res); } } printf("Create treads success\n Waiting for threads to finish...\n"); for (no = 0; no < THREAD_NUMBER; no++) { /* 等待線程結束 */ res = pthread_join(thread[no], &thrd_ret); if (!res) { printf("Thread %d joined\n", no); } else { printf("Thread %d join failed\n", no); } } return 0; }
例程中循環3次建立3條線程,並且使用pthread_join函數依次等待線程結束;
線程中使用rand()獲取隨機值隨機休眠5次,隨意會出現后執行的線程先執行完成;
運行結果:
$ gcc thread.c -lpthread $ ./a.out Create treads success Waiting for threads to finish... Thread 0 is starting Thread 1 is starting Thread 2 is starting Thread 1: job 0 delay = 2 Thread 1: job 1 delay = 2 Thread 0: job 0 delay = 8 Thread 2: job 0 delay = 10 Thread 2: job 1 delay = 3 Thread 1: job 2 delay = 10 Thread 0: job 1 delay = 8 Thread 0: job 2 delay = 3 Thread 0: job 3 delay = 1 Thread 2: job 2 delay = 8 Thread 1: job 3 delay = 8 Thread 1: job 4 delay = 1 Thread 1 finished Thread 2: job 3 delay = 6 Thread 0: job 4 delay = 7 Thread 0 finished Thread 0 joined Thread 1 joined Thread 2: job 4 delay = 10 Thread 2 finished Thread 2 joined
可以看到,線程1先於線程0執行,但是pthread_join的調用時間順序,先等待線程0執行;
由於線程1已經早結束,所以線程0被pthread_join等到的時候,線程1已結束,就在等待到線程1時,直接返回;
2. 線程執行的互斥和同步pthread_mutex_lock
下面我們在上面的程序中增加互斥鎖:
/*thread_mutex.c*/ #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #define THREAD_NUMBER 3 /* 線程數 */ #define REPEAT_NUMBER 3 /* 每個線程的小任務數 */ #define DELAY_TIME_LEVELS 10.0 /*小任務之間的最大時間間隔*/ pthread_mutex_t mutex; void *thrd_func(void *arg) { int thrd_num = (int)arg; int delay_time = 0, count = 0; int res; /* 互斥鎖上鎖 */ res = pthread_mutex_lock(&mutex); if (res) { printf("Thread %d lock failed\n", thrd_num); pthread_exit(NULL); } printf("Thread %d is starting\n", thrd_num); for (count = 0; count < REPEAT_NUMBER; count++) { delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1; sleep(delay_time); printf("\tThread %d: job %d delay = %d\n", thrd_num, count, delay_time); } printf("Thread %d finished\n", thrd_num); /****互斥鎖解鎖***/ pthread_mutex_unlock(&mutex); pthread_exit(NULL); } int main(void) { pthread_t thread[THREAD_NUMBER]; int no = 0, res; void * thrd_ret; srand(time(NULL)); /* 互斥鎖初始化 */ pthread_mutex_init(&mutex, NULL); for (no = 0; no < THREAD_NUMBER; no++) { res = pthread_create(&thread[no], NULL, thrd_func, (void*)no); if (res != 0) { printf("Create thread %d failed\n", no); exit(res); } } printf("Create treads success\n Waiting for threads to finish...\n"); for (no = 0; no < THREAD_NUMBER; no++) { res = pthread_join(thread[no], &thrd_ret); if (!res) { printf("Thread %d joined\n", no); } else { printf("Thread %d join failed\n", no); } } pthread_mutex_destroy(&mutex); return 0; }
在上面的例程中直接添加同步鎖pthread_mutex_t;
在線程中加入,程序在執行線程程序時,調用pthread_mutex_lock上鎖,發現上鎖時候后進入等待,等待鎖再次釋放后重新上鎖;
所以線程程序加載到隊列中等待,等待成功上鎖后繼續執行程序代碼;
運行結果如下:
Create treads success Waiting for threads to finish... Thread 0 is starting Thread 0: job 0 delay = 7 Thread 0: job 1 delay = 2 Thread 0: job 2 delay = 9 Thread 0 finished Thread 2 is starting Thread 0 joined Thread 2: job 0 delay = 6 Thread 2: job 1 delay = 7 Thread 2: job 2 delay = 10 Thread 2 finished Thread 1 is starting Thread 1: job 0 delay = 3 Thread 1: job 1 delay = 5 Thread 1: job 2 delay = 2 Thread 1 finished Thread 1 joined Thread 2 joined
