並行性制御を多重IOのファイルディスクリプタに基づいて実施、このセクションでは、マルチスレッドに基づく並行プログラミングを記録しました。
1.スレッドとプロセス
プロセスは、リソース管理システムのデータセットの個々の機能を有するアクティブなプログラムは、リソース割当の基本単位で実行され、この文であるが、スレッドは、(コードが実行されるフロー処理、スケジューリングシステムの基本単位であります一般的な、しかし、それはユーザレベルスレッドとカーネルレベルのスレッドが異なる用語を思えあり、それは)後述します。自分のスペースに加えて、同じプロセス内のスレッドが、また、リソースを共有するプロセス。スレッドとプロセスとの間の差は、図1.1に示されています。
(A)は、単一のスレッド(b)は、マルチスレッド
図1.1プロセスとスレッド
プロセスが作成されるとき、それは、システムに割り当てられたアドレス空間を見ることができ、プロセスは、独自のコードセグメントと、データセグメントとスタックを有しています。そして、あなたは、独自のスタックを維持しながら、プロセスのアドレス空間を共有するスレッドを作成するとき。それに細分、スレッドはユーザレベルスレッド(ユーザレベルスレッド、ULT)及びカーネルレベルのスレッド(カーネルレベルスレッド、KLT)に分けることができます。
1.1 KLTおよびULT(PS:このセクションでは、唯一のオペレーティングシステムの概念は、ユーザプログラムをマルチスレッド化されています)
異なるオペレーティングシステムは、わずかに異なる方法でスレッドを実装し、いくつかのオペレーティングシステムを直接サポートスレッド(KLT);他のものは、オペレーティング・システムのスレッドの存在を認識しながら、ユーザ空間ライブラリ関数を介して達成されるスレッド管理を達成するために( ULT)。
KLTはによって投与しないOSを実行するために、この時間直接スレッドをスケジューリングするOSは、プロセスがもはやマルチステートた(のみ中断および非中断します)。主な機能は次のとおりです。
(1)スレッドがブロックされているプロセスは、OSが実行するプロセスの他のスレッドを呼び出します。
(2)マルチプロセッサ環境では、カーネルは、並列実行スレッド(物理パラレル)の複数を呼び出し、
(3)ユーザモードでアプリケーション、カーネルモードでスケジューリングスレッド。スケジューリングモード切替、大規模なシステムのオーバーヘッドをスレッドに。
ULTは、カーネルスレッドが存在を気付いていないマルチスレッド。マルチスレッドはユーザ空間のスレッドライブラリによって達成されます。主な機能は次のとおりです。
ユーザ空間内のスレッド管理のためのデータ構造(1)は、スケジューリングモードの切り替えを必要としません。
(2) (ユーザがライブラリ機能を実装されているため)、スレッドスケジューリングアルゴリズムは選択してカットすることができます。
(3)マルチプロセッサの利点を利用することができないOSを呼び出すプロセスは、プロセスが実行のスレッドが1つしかありません。スレッドがブロックにプロセス全体を引き起こして、ブロックされています。
解決するためにULTブロッキングの問題につながるプロセスブロックされたスレッドを、導入の技術を外被、技術を外被を阻止することができる場合、スレッドかどうか切り替え処理又は他のスレッドへの制御の移転。
また、マルチスレッド第三のハイブリッドがあります。ハイブリッドマルチスレッドマルチスレッドユーザ空間で作成ULT (ユーザが作成した複数のスレッドを作成するために、カーネル空間ながら、)KLTを。複数のULTはにマッピングされ(以下ULLTの数KLT間)。プログラマは、調整することができますKLTの数を。KLTによって送出OS、責任ユーザスケジューリングによってULTのトライステート、およびアクティブ状態ULTはにバインドされたKLT。図に示すように、3つの方法の比較。1.2。
図の三種類の1.2比較は、マルチスレッド
(注:図はより引用https://www.cnblogs.com/Mered1th/p/10745137.html)
2. Linuxのマルチスレッドの下で達成
次のようにライブラリの関数の主な用途pthread.hのLinuxのマルチスレッド実装は、主な機能は次のとおりです。
int型のpthread_create(がpthread_t *スレッド、ATTR、制限無効 *(* start_routineが)(無効 *)を、無効 * 引数を制限します)。 スレッド:スレッドIDを保持する変数。 ATTR:NULLに属性セット。 start_routineは:スレッドの開始関数を、入力パラメータや戻り値がvoidポインタです。 引数:引数は、スレッドに渡されます 自動的に次の2つの方法の終了後に破壊され、作成されたスレッドを作るために: (1 スレッド作成のプロセスによって呼び出される) int型(スレッド、がpthread_t pthread_joinを無効 ** ステータス)。 スレッド:スレッドID待ち ステータス:プロセス・パラメータに戻ります (2 最後のコール)スレッド int型(スレッドがpthread_t)pthread_detachの。
非常に簡単で、我々はまだのように、次のマルチスレッドコードにそれを回す、例えば、サーバー側のコードにサーバーをされてエコーします。
1の#include <STDLIB.H> 2の#include <stdio.hの> 3の#include < 文字列・H> 4の#includeは<sys / socket.hに> 5の#include <ARPA / inet.h> 6の#include <unistd。 H> 7の#include <pthread.hの> 8 9 ボイド error_handle(CONST 文字 * MSG) 10 { 11 fputs(MSG、標準エラー出力) 12 FPUTC(' \ n ' 、標準エラー出力)。 13 出口(1 )。 14 } 15 空隙Client_thread *(ボイド *アルギニン); // スレッド処理機能 16 17。 INTメイン(int型 ARGC、CHAR * ARGV []) 18である { 19の。 // サーバーへの接続 20 INT servsock、clntsock; 21である ストラクトのsockaddr_in servaddr、clntaddrを、 22である CHARメッセージ[ 50 ]; 23がある のsocklen_t clntlen = はsizeof (clntaddr);; 24 25 IF(!のargc = 2 ) 26がある (error_handle 」を入力してくださいポート番号" ); 27 28 servsock =ソケット(PF_INET、SOCK_STREAM、0); // 1.確立ソケット 29 30 のmemset(&servaddr、0、はsizeof (servaddr)); 31である servaddr.sin_family = AF_INET; 32 servaddr.sin_addr。 = htonl s_addr(INADDR_ANY); // デフォルトのローカルIPアドレス 33がある servaddr.sin_port = htons(ATOI(ARGV [ 1。)]); 34である 35 IF(バインド(servsock、(ストラクトのsockaddr *)&servaddr、はsizeof(servaddr))を== - 1 ) 36 error_handle(" バインドエラーを"); // 2.接続確立 37 [ 38である IF(servsock、(聞く10 ==) - 1。 )// 3.リスナー確立 39 error_handle(" 聞く()エラー" ); 40 41である // このソケット作成処理のためのコードは、同一の四分の三 42である ;がpthread_t t_id // スレッドIDセーブ 43が しばらく(1 ) 44は 、{ 45 clntsock =((servsockを受け入れストラクトのsockaddr *)&clntaddrを、&clntlen); // クライアント接続 46 IF(clntsock == - 1 ) 47 { 48 のprintf(" 受け入れる()エラー" )。 49 近い(clntsock)。 50 } 51 他{ 52 のpthread_create(&t_id、NULL、client_thread、(ボイド *)&clntsock)。 53 pthread_detachの(t_id)。 54 のprintf(" 接続" )。 55 } 56 } 57 58 } 59 60 ボイド * client_thread(ボイド * 引数) 61 { 62 チャーメッセージ[ 30 ]。 63 INT靴下= *((INT * )引数)。 64 int型はstrlenを。 65 一方、(1 ) 66 { 67 strlenを=(靴下、メッセージ、読み取りはsizeof (メッセージ))。 68 であれば(STRLEN == 0) // 断开连接 69 { 70 近く(靴下) 71 ブレーク; 72 } 73 もし(strlenを> 0 ) 74 ライト(靴下、メッセージ、strlenを)。 75 } 76 77 }
PS:Linuxでは、コードをコンパイルするときは、このようなserver.cppという名前の上記のコードファイルとして、スレッドライブラリに追加する必要があります。そして、コンパイラのコマンド:G ++ server.cpp -g -o -lpthread