そのスレッドスケジューラに従ってユーザレベルスレッドと、カーネルレベルスレッド2種類に分けることができます
ユーザーレベルのスレッドは、それが実行時に特定のカーネルのサポートを必要としない、主な問題は、そのコンテキストの切り替えでそのスケジューリングアルゴリズムとユーザが自分ですべての選択決定のスケジューリングを解決するために、
私たちが使用されている基本的なユーザレベルスレッドで、我々は唯一のPOSIXをまとめてインタフェースは、ユーザレベルスレッドを提供し、
基本的なスレッド動作に関連する機能:
1確立する糸の端
二つの相互に排他的と同期スレッド
のスレッドの量を制御するための信号を用いて3
4つのスレッドの基本的な特性は、配置された
実質的操作をスレッド。
機能 | 説明 |
---|---|
pthread_create() | スレッド関連の機能を実行するスレッドを起動すると、実行中のスレッド出口の終わりを作成します。 |
pthread_eixt() | 出口は()プロセスを終了するために使用されているので、あなたは、スレッドの終了の特定の機能を使用する必要があります |
pthread_joinを() | スレッドは、直ちに0 =成功を返す終了した場合、スレッドの終了を阻止するのを待っている、現在のスレッドを一時停止 |
pthread_cancel() | それが成功すると0を返しますが、成功は、スレッドが終了することを意味するものではありません、スレッドのスレッドに終了信号を送ります |
pthread_testcancel() | 取り消しポイントが含まれていない場所でのキャンセルポイントを作成しますが、それはキャンセル要求に応答して、コード実行スレッドの取り消しポイントが含まれていないので、彼らは、ポイントをキャンセルする必要があります。 |
pthread_setcancelstate() | このスレッドは、キャンセル信号に応答して提供されます |
ます。pthread_setcanceltype() | キャンセル状態を設定すると、すぐにキャンセルアクションの実装を次のポイントに実行し、その後撤回またはキャンセルし続け |
pthread_setcancel() | セット状態が解除さ |
相互排除と同期メカニズムの基本的な機能
機能 | 説明 |
---|---|
pthread_mutex_initの() | ミューテックスの初期化 |
pthread_mutex_lockの() | あなたはmutexをロックしようとした場合の閉塞が利用可能になるとミューテックスロックは、ロックされています |
pthread_mutex_trylockの() | ノンブロッキングロックミューテックス |
pthread_mutex_unlockの() | リリースミューテックス |
pthread_mutex_destory() | ミューテックスデストラクタ |
セマフォスレッド制御(デフォルト名前なしセマフォ)
機能 | 説明 |
---|---|
sem_init(ありません) | 匿名セマフォをSEMに配置されている初期化 |
sem_wait() | 操作信号マイナス1、閉塞0にセマフォの現在の値、アトミック操作であれば |
sem_trywait() | セマフォの現在の値が0のエラーが代わりに(エラー番号= EAGAIN)呼び出しをブロック返された場合、実際には、()sem_waitで、非ブロッキングバージョンです |
sem_post() | 同じ量が1つの信号に加えられたことながら、「アトミックオペレーション」、すなわち、あるセマフォ値プラス1に、二つのスレッドの動作が競合しません |
sem_getvalue(SVAL) | 信号の量にSEMポイントは整数向けSVALの電流値に配置されています |
sem_destory(無料) | 匿名は、SEMが指すセマフォによって破壊されました |
関連のプロパティ設定機能スレッド
機能 | 説明 |
---|---|
pthread_attr_init() | スレッド・オブジェクト属性の初期設定、あなたはは、pthread_attr_destroy機能を既存のプロパティを削除する必要があります |
pthread_attr_setscope() | セットスレッド属性 |
pthread_attr_setschedparam() | セットのスレッドの優先順位 |
pthread_attr_getschedparam() | スレッド優先順位を取得します。 |
基本的な糸走行pthread_createの確立
-
/* 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つのスレッド、および使用はpthread_join機能を確立するためのルーチン3サイクル;
実行のランダムなスレッドが最初に完成する予定後の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スレッドのを待って、直接のリターンを終了しました。
相互排除と同期スレッド実行pthread_mutex_lockの
上記の手順でミューテックスの増加
-
/*thread_mutex.c*/
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <pthread.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_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_unlock(&mutex);
-
pthread_mutex_destroy(&mutex);
-
return 0;
-
}
- 直接ルーチンpthread_mutex_t同期ロックの上に追加されました。
プログラムは、スレッドプログラムを実行されるように、スレッドに参加;
; pthread_mutex_lockのロック呼び出して、待機を入力するときにロックが再び解放された後に再ロックを待って、ロックされた
ので、スレッドプログラムが正常にロック解除続けるのを待って、待ち行列にロードプログラムコードを実行するステップと、
動作の結果を
-
$gcc thread_mutex.c -lpthread
-
$ ./a.out
-
Create treads success
-
Waiting for threads to finish...
-
Thread 0 is starting
-
Thread 0: job 0 delay = 9
-
Thread 0: job 1 delay = 4
-
Thread 0: job 2 delay = 7
-
Thread 0 finished
-
Thread 0 joined
-
Thread 1 is starting
-
Thread 1: job 0 delay = 6
-
Thread 1: job 1 delay = 4
-
Thread 1: job 2 delay = 7
-
Thread 1 finished
-
Thread 1 joined
-
Thread 2 is starting
-
Thread 2: job 0 delay = 3
-
Thread 2: job 1 delay = 1
-
Thread 2: job 2 delay = 6
-
Thread 2 finished
-
Thread 2 joined
- 異なる実行結果との1つのルーチンは、スレッドプログラムは、それが正常にロックするのを待つ、直ちに実行することができないキューにロードされます。
ロックした後、プログラムは、スレッド、ロックの実行を実行し続け、
そのようなスレッドの場合は、多くの場合、実際の使用状況で発生する順序で実行され、
使用シナリオ:
ユーザーは、ユーザーの基本情報を引き続き入手するために秘密鍵を取得するためにログオンすると、待ち時間に我々は、スレッドのスレッドの終了後に、ユーザ情報のログを取得するために進むことができたときに
それがある場合には、二つのスレッドを呼び出す必要があります:threadLogin()、threadGetInfo() ; あなたは方法の2種類持つことができます。
この時点では1を、あなたは使い捨てながら、ミューテックスを使用することができますエンドコールthreadLogin()とthreadGetInfo();
2コースコールthreadGetInfo(ログイン認証成功に直接threadLogin後ミューテックス())を使用することができない。
これに対し、より鮮明な表示モード・ロジック、内のコードを追加します読みやすさのスケーラビリティ。
セマフォを使用して実行スレッドの順序を制御するsem_post
上記pthread_mutex_lockのミューテックス制御スレッドの実行順序を使用して、上記のルーチンを変更する
実行順序のスレッドに追加の制御を使用して、
-
/* thread_sem.c */
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <pthread.h>
-
#include <semaphore.h>
-
#define THREAD_NUMBER 3
-
#define REPEAT_NUMBER 3
-
#define DELAY_TIME_LEVELS 10.0
-
sem_t sem[THREAD_NUMBER];
-
void * thrd_func(void *arg) {
-
int thrd_num = (int)arg;
-
int delay_time = 0;
-
int count = 0;
-
sem_wait(&sem[thrd_num]);
-
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++) {
-
sem_init(&sem[no], 0, 0);
-
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");
-
sem_post(&sem[THREAD_NUMBER - 1]);
-
for (no = THREAD_NUMBER - 1; no >= 0; no--) {
-
res = pthread_join(thread[no], &thrd_ret);
-
if (!res) {
-
printf("Thread %d joined\n", no);
-
} else {
-
printf("Thread %d join failed\n", no);
-
}
-
sem_post(&sem[(no + THREAD_NUMBER - 1) % THREAD_NUMBER]);
-
}
-
for (no = 0; no < THREAD_NUMBER; no++) {
-
sem_destroy(&sem[no]);
-
}
-
return 0;
-
}
結果はまだ3つのスレッド、睡眠長いランダム実行に各スレッドを構築します:
-
$ gcc thread_sem.c -lpthread
-
$ ./a.out
-
Create treads success
-
Waiting for threads to finish...
-
Thread 2 is starting
-
Thread 2: job 0 delay = 9
-
Thread 2: job 1 delay = 9
-
Thread 2: job 2 delay = 5
-
Thread 2 finished
-
Thread 2 joined
-
Thread 1 is starting
-
Thread 1: job 0 delay = 5
-
Thread 1: job 1 delay = 7
-
Thread 1: job 2 delay = 4
-
Thread 1 finished
-
Thread 1 joined
-
Thread 0 is starting
-
Thread 0: job 0 delay = 3
-
Thread 0: job 1 delay = 9
-
Thread 0: job 2 delay = 8
-
Thread 0 finished
-
Thread 0 joined
最初の2つのルーチンの結果教科書のみ逆に実行されることを除いて、非常に類似しており、
それ実際にミューテックスを使用するよりも、このようにして、同等のコードの読みやすさの基本的に同じ量。
基本的な性質は、スレッドをpthread_attr_setscope
一般的に提供するプロパティ:
結合特性
分離財産
3アドレス・スタック
4スタックサイズ
5優先順位
結合性は、カーネルスレッドにバインドされ、
別のプロパティ、直ちにトークスレッドの後に対応するメモリを解放主にするかどうか。
-
/* thread_attr.c */
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <pthread.h>
-
#define THREAD_NUMBER 1
-
#define REPEAT_NUMBER 3
-
#define DELAY_TIME_LEVELS 10.0
-
int finish_flag = 0;
-
void * thrd_func(void * arg){
-
int delay_time = 0;
-
int count = 0;
-
printf("Thread is starting\n");
-
for (count = 0; count < REPEAT_NUMBER; count++) {
-
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
-
sleep(delay_time);
-
printf("\tThread : job %d delay = %d\n", count, delay_time);
-
}
-
printf("Thread finished\n");
-
finish_flag = 1;
-
pthread_exit(NULL);
-
}
-
int main(void) {
-
pthread_t thread;
-
pthread_attr_t attr;
-
int res = 0;
-
srand(time(NULL));
-
res = pthread_attr_init(&attr);
-
if (res != 0) {
-
printf("Create attribute failed\n");
-
exit(res);
-
}
-
res = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
-
res += pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
if (res != 0) {
-
printf("Setting attribute failed\n");
-
exit(res);
-
}
-
res = pthread_create(&thread, &attr, thrd_func, NULL);
-
if (res != 0) {
-
printf("Create thread failed\n");
-
exit(res);
-
}
-
pthread_attr_destroy(&attr);
-
printf("Create tread success\n");
-
while(!finish_flag){
-
printf("Waiting for thread to finish...\n");
-
sleep(2);
-
}
-
return 0;
-
}
使用前と発見の前と後のメモリ使用量を表示した後フリーランコマンドを$:
メモリは、スレッドの終了直後にリリースされ、
実際には、属性の一般的なスレッドは、直接、システムのデフォルトのプロパティを使用することができ、
スレッド上で使用する、ほぼので、
すべてのルーチンから:「組込みLinuxアプリケーション開発標準のチュートリアル」