スレッドとは: 軽量プロセスと呼ばれることもあり、プログラム実行フローの最小単位です。
標準スレッドは、スレッドID、現在の命令ポインタ(PC)、レジスタセット、スタックで構成されます。
プロセスは 1 つから複数のスレッドで構成され、各スレッドはプログラムのメモリ空間 (コード セグメント、データ セグメント ヒープなど) と一部のプロセス レベルのリソース (オープン ファイルやシグナルなど) を共有します。相互に干渉することなく同時に実行し、プロセスのグローバル変数とヒープ データを共有します。
スレッド アクセス権限スレッド アクセス権限は非常に自由で、プロセス メモリ内のすべてのデータにアクセスできます
スレッドのスケジューリングと優先度
シングルプロセッサはマルチスレッドに対応します。オペレーティングシステムはこれらのマルチスレッドを順番に実行することを許可しており、毎回短時間(通常は数十秒)のみ実行するため、それぞれのスレッドがスレッドが「アップ」と見えることは、同時に実行しているようなもので、そのようなプロセッサー上でスレッドを常に切り替える操作は「スレッド スケジューリング」になります
スレッド スケジューリングの 3 つの状態:
(
1) : 実行中、この時点でスレッドは実行中です
(2): 準備完了、現時点ではスレッドはすぐに実行できますが、CPUが占有されています
(3 ): 待機中。現時点では、スレッドは特定のイベントの発生を待機しているため、実行できません。プログラムが実行状態を離れるたびに、スケジューリング システムは待機状態のスレッドを選択します。イベントが発生すると準備完了状態になります。
優先度スケジューリングの場合、スレッドの優先度を変更するには、一般に 3 つの方法があります。
ユーザー指定の優先度
待機状態に入る頻度に応じて優先度を上げたり下げたりします。 長時間実行されないため優先度が高くなります。
Linux マルチスレッド Linux では、次の 3 つの方法を使用して新しいタスクを作成できます: (1) fork: 現在のプロセスをコピーします。 (2) exec: 現在の実行可能イメージを新しい実行可能イメージで上書きします (3) clone: 子プロセスを作成し、指定された場所から実行を開始します fork: pid_t pid; (pid==fork( )){…} fork 呼び出しの後、新しいタスクが開始され、このタスクとともに fork 関数から返されますが、違いは、このタスクのフォークがタスクの pid を返すことです。新しいタスクの場合、新しいタスクのフォークは 0 を返します。フォークは元のタスクのメモリ空間をコピーせず、コピーオンライト
のメモリ空間を共有するため、新しいタスクを非常に迅速に生成します。元のタスク;
いわゆる
コピーオンライト
: 2つのタスクが同時にメモリを自由に読み取ることができますが、いずれかのタスクがメモリを変更しようとすると、他のタスクの使用に影響を与えないように、メモリは個別に使用するために変更者に提供されます。
fork はこのタスクのイメージのみを生成できるため、他の新しいタスクを開始するには exec を使用する必要があります。 task.exec は現在の実行可能イメージを新しい実行可能イメージに置き換えることができるため、新しいタスクが fork で生成されます。その後、新しいタスクは exec を呼び出して新しい実行可能ファイルを実行できます。ヘッダー ファイルは pthread.h で定義されます。スレッドを作成します: #include
スレッドパラメータは、新しいスレッド、および後続の pthread_* 関数はそれを使用して新しいスレッドを参照します;
attr パラメータは、新しいスレッドの属性を設定するために使用されます。それに NULL を渡すと、
Start_routine パラメータと arg パラメータは、それぞれ新しいスレッドが実行する関数とパラメータを指定します。成功した場合はエラー、失敗した場合はエラー。
マルチスレッド プログラムは変化する環境にあり、アクセス可能なグローバル変数とヒープ データは他のスレッドによっていつでも変更される可能性があります。 意味: 同期とロックアトミック:
単一の命令操作はアトミックと呼ばれます。この場合、単一の命令の実行は中断されません複数のスレッドが同時にデータを読み書きすることによって引き起こされる予期せぬ結果を避けるために、同じデータへの各スレッドのアクセスを同期する必要があります (いわゆる同期とは、あるスレッドが終了する前にデータにアクセスすると、他のスレッドが同じデータにアクセスすることを許可されないことを意味します。したがって、データへのアクセスはアトミックです。
一般的な同期方法: (セマフォ、ミューテックス、クリティカル セクション、読み取り)。 -書き込みロック、条件変数)
ロック: 各スレッドは、データまたはリソースにアクセスするときに最初にロックの取得を試み、アクセスが完了した後にロックを解放します。セマフォ: スレッドがリソースにアクセスすると、最初にロックを取得します。セマフォ;
操作は次のとおりです: (1) セマフォの値が 1 ずつ減ります。リソースにアクセスした後、スレッドはセマフォを解放します。
(3) セマフォを値に追加します。(4) セマフォの値が 1 未満の場合、待機中のスレッドを起動します。 mutex&&セマフォ同じ: リソースは同時に 1 つのスレッドのみにアクセスできます。
違い: つまり、セマフォはシステム全体のどのスレッドでも取得および解放できます。 、同じセマフォはシステム内の 1 つのスレッドによって取得され、その後、別のスレッドによって解放される可能性があります。
そして、ミューテックスは、スレッドがミューテックスを取得するときに、ロックの解放を担当するスレッドが他のスレッドに対して無効であることを要求します。スレッドが代わりにミューテックスを解放します。
クリティカル セクション: は、ミューテックスよりも厳密な同期方法です。クリティカル セクション ロックの取得はクリティカル セクションに入ると呼ばれ、ロックの解放は終了と呼ばれます。クリティカルセクション。 違い (セマフォとミューテックス)
ミューテックスとセマフォはシステムのどのプロセスでも見ることができます;
つまり、あるプロセスがミューテックスまたはセマフォを作成し、別のプロセスがミューテックスまたはセマフォを作成することは合法です。プロセスがロックを取得しようとする場合、
クリティカルセクションの範囲はこのプロセスに限定され、他のプロセスはロックを取得できません。
2つの方法: 共有と排他。
ロックが解放状態にある場合、何らかの方法でロックを取得しようとすると成功し、ロックが対応する状態になります (上記のように)
条件変数:同期の手段として、機能はフェンスと似ています。
条件変数の場合、スレッドには 2 つの操作があります:
(1) まず、スレッドは条件変数を待機でき、条件変数は複数のスレッドで待機できます。スレッドは条件変数をウェイクアップできます。この時点で、この条件変数を待機している 1 つまたはすべてのスレッドがウェイクアップされ、
のサポートを継続します (つまり、条件変数を使用すると、多くの既存のスレッドがイベントを待機できるようになります。イベントが発生すると、すべてのスレッドの実行を一緒に再開できます)。 関連記事:
プロセスとは何ですか?Java学習におけるマルチスレッドの実装方法をベースにしています
以上がJava の学習: スレッドとは何ですか?最も詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。