基本的なスレッドプログラミング
1.スレッドの紹介
プロセッサのアイドル時間をさらに削減し、マルチプロセッサをサポートし、コンテキスト切り替えのオーバーヘッドを削減するために、進化スレッドのプロセスに別の概念が現れます。これは、プロセス内の独立した実行ラインであり、プロセッサスケジューリングの最小単位であり、軽量プロセスとも呼ばれます。スレッドは効率と操作性が高いため、組み込みシステム開発で広く使用されています。
プロセス内の複数のスレッドによって共有されるリソースには、実行可能命令、静的データ、プロセスで開かれたファイル記述子、現在の作業ディレクトリ、ユーザーID、およびユーザーグループIDが
含まれます。各スレッドにプライベートなリソースには、スレッドID(TID)が含まれます。 )、PC(プログラムカウンター)および関連レジスター、スタック、エラー番号、優先順位、実行ステータスおよび属性
2.プログラミング手順
Linuxでは、一般的なpthreadスレッドライブラリは、POSIXによって提案された一般的なスレッドライブラリのセットであり、優れた移植性を備えています。pthreadスレッドライブラリは、次の基本的な操作を提供します。
- スレッドの作成:スレッド関数を呼び出すエントリポイントを決定し、pthread_create()関数を使用します
- スレッドのリサイクル:スレッドが終了した後、そのスレッドが占有しているリソースを解放し、pthread_join()関数を使用します。
- 終了スレッド:終了スレッドはスレッドのアクティブな動作です。pthread_exit()関数を使用してください
- スレッド内の別のスレッドを終了します。pthread_cancel()関数を使用します
3.機能紹介
pthread_create()
/*****pthread_create()函数*****/
函数原型:int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void*),void *arg)
传 入 值:thread 线程标识符
attr 线程属性设置(详见属性介绍章节),通常取为NULL
start_routine 线程函数的起始地址,是一个以指向void的指针作为参数和返回值的函数指针
arg 传递给 start_routine 的参数
返 回 值:成功:返回0;失败:返回错误码
pthread_join()
/*****pthread_join()函数*****/
函数原型:int pthread_join(pthread_t th,void **thread_return)
传 入 值:th 等待线程的标识符
thread_return 用户定义的指针,用来存储被等待线程结束时的返回值(不为NULL时)
返 回 值:成功:返回0;失败:返回错误码
pthread_exit()
/*****pthread_exit()函数*****/
函数原型:void pthread_exit(void *retval)
传 入 值:retval 线程结束时的返回值,可由其他函数如pthread_join()来获取
pthread_cancel()
/*****pthread_cancel()函数*****/
函数原型:int pthread_cancel(pthread_t th)
传 入 值:th 要取消的线程的标识符
返 回 值:成功:返回0;失败:返回错误码
4.プログラミング例
次の例では、3つのスレッドを作成します。スレッド間の並列実行を詳しく説明するために、3つのスレッドが実行関数を共有するようにします。各スレッドには5サイクルあり、各サイクルは1〜10秒ランダムに待機します。つまり、各タスクの到着時間はシミュレーションされ、特定のルールはありません。
/*****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(){
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 thread sucess\nWaiting for threads to finish...");
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;
}
以下は実行結果です。各スレッドの実行と終了は、無秩序で独立しており、並列であることがわかります
linux@linux-virtual-machine:~/andy/proc$ ./thread
Create threads sucess
Waiting for threads to finish...
Thread 0 is starting
Thread 1 is starting
Thread 2 is starting
Thread 1: job 0 delay = 6
Thread 2: job 0 delay = 6
Thread 0: job 0 delay = 9
Thread 1: job 0 delay = 6
Thread 2: job 0 delay = 8
Thread 0: job 0 delay = 8
Thread 2 finished
Thread 1: job 2 delay = 10
Thread 1: job 3 delay = 4
Thread 1: job 4 delay = 1
Thread 1 finished
Thread 0: job 3 delay = 9
Thread 0: job 4 delay = 2
Thread 0 finished
Thread 0 joined
Thread 1 joined
Thread 2 joined