8.6マルチタスクの紹介

13147 ワード

マルチタスクの紹介
1.現実のマルチタスク
アニメを見ながら食事
2.コンピュータ内のマルチタスク
コンピュータ内のマルチタスクとは、オペレーティングシステムが複数のタスクを同時に完了する処理です.ここでは、ある瞬時の時点ではなく、同じ期間内を指す.
マルチタスク処理とは、ユーザが同じ時間帯に複数のアプリケーションを実行することであり、各アプリケーションを1つのタスクと呼ぶことができる.
現在、マルチコアCPUは非常に普及しているが、従来のシングルコアCPUであってもマルチタスクを実行することができる.CPU実行コードはすべて順番に実行されるので、シングルコアCPUはどのようにマルチタスクを実行しますか?
答えは,オペレーティングシステムが交代で各タスクを交互に実行し,タスク1が0.01秒,タスク2に切り替え,タスク2が0.01秒,さらにタスク3に切り替え,0.01秒…と繰り返し実行することである.表面的には、各タスクは交互に実行されていますが、CPUの実行速度が速すぎるため、すべてのタスクが同時に実行されているような気がします.
真のパラレルマルチタスクはマルチコアCPUでしか実現できませんが、タスク数がCPUのコア数よりはるかに多いため、オペレーティングシステムは自動的に多くのタスクを各コアに順番にスケジューリングして実行します.
同時および並列
  • 同時処理(concurrency Processing):1つの期間のうちいくつかのプログラムが起動実行から実行完了までの間にあり、これらのプログラムはいずれも同じプロセッサ(CPU)上で実行するが、いずれの時点でも1つのプログラムだけがプロセッサ(CPU)上で
  • を実行する.
  • 並列処理(Parallel Processing):コンピュータシステムにおいて2つ以上の処理を同時に実行できる計算方法である.パラレル処理は、同じプログラムの異なる側面で同時に動作することができる.パラレル処理の主な目的は、大規模で複雑な問題の解決時間を節約することです.

  • 同時に重要なのは、複数のタスクを処理する能力があり、必ずしも同時に必要としないことです.パラレルの鍵は、複数のタスクを同時に処理する能力があることです.したがって,並列は同時サブセットである.
    [外部リンク画像の転送失敗(img-E 5 knQ 031-156508746260)(/Users/shaojun/Library/Application Support/typora-user-images/image-20190806140127545.png)]
    import time
    
    
    def download_music():
        """      ,  5      """
        for i in range(5):
            time.sleep(1)  #   1 
            print("-----      %d----" % i)
    
    
    def play_music():
        """      ,  5      """
        for i in range(5):
            time.sleep(1)  #   1 
            print("-----      %d----" % i)
    
    
    def main():
        #      
        download_music()
        #      
        play_music()
    
    
    if __name__ == '__main__':
        main()
    

    プロセスの作成
    ≪プロセス|Process|emdw≫:プログラムの実行例.各プロセスは、プログラムを実行するために必要なすべてのリソースを提供します.
    プロセスは本質的にリソースの集合である.
    1つのプロセスには仮想アドレス空間、実行可能なコード、オペレーティングシステムのインタフェース、安全なコンテキスト(プロセスを開始するユーザーと権限などを記録する)、一意のプロセスID、環境変数、優先度クラス、最小と最大のワークスペース(メモリ空間)、さらに少なくとも1つのスレッドがあります.
    プロセスの作成---fork()
    pythonのosモジュールには、一般的なシステム呼び出し関数がカプセル化されています.
    Unix/Linuxではfork()システム関数が提供されています
    普通の関数呼び出し、1回呼び出し、1回返します.
  • fork()は1回呼び出され、2回返されます.
  • オペレーティングシステムは、現在のプロセス(親プロセス)を自動的にコピーし(子プロセス)、親プロセスと子プロセスでそれぞれ返します.


  • fork()サブプロセスは常に0を返し、親プロセスはサブプロセスのIDを返します.
    親プロセスはforkの多くのサブプロセスを実行できます.親プロセスは、各サブプロセスのIDをメモすることができ、サブプロセスはgetppid()を呼び出すだけで親プロセスのIDを取得できます.
  • getpid()は、現在のプロセスID
  • を返します.
  • getppid()は、親プロセスID
  • を返します.
    import os
    
    pid = os.fork()
    if pid < 0:
        print("fork     。")
    elif pid == 0:
        print("     :\t%s,      :\t%s" % (os.getpid(), os.getppid()))
    else:
        print("     :\t%s,      :\t%s" % (os.getpid(), pid))
    
    print("           。")
    

    スレッド
    スレッドは、オペレーティングシステムがスケジューリングを演算できる最小単位です.スレッドはプロセスに含まれ、プロセス内の実際の動作単位です.
    1つのスレッドはプロセス内の単一の順序の制御フローであり、1つのプロセスは複数のスレッドを同時に実行することができ、各スレッドが並列に実行する異なるタスク
    1つのスレッドはexecution context(実行コンテキスト)、すなわちcpuの実行に必要な一連の命令である.
    スレッドの働き方は、本を読んでいて、読んでいないと仮定して、休みたいと思っていますが、帰ってきたら、その時に読んだ具体的な進捗状況に戻りたいと思っています.ページ数、行数、文字数の3つの数値をメモする方法があります.これらの数値はexecution contextです.もしあなたのルームメイトがあなたが休んでいる間に、同じ方法でこの本を読んでいたら.あなたと彼女はこの3つの数字を覚えるだけで、交代の時間にこの本を読むことができます.
    スレッドの動作はこれと似ています.CPUは同じ時間に複数の演算ができる幻覚を与えますが、実際には各演算にわずかな時間しかかかりません.本質的にはCPUは同じ時間に1つのことしかしていません.これは、各演算のexecution contextがあるためです.同じ本を友達と共有できるように、マルチタスクでも同じCPUを共有できます.
    プロセスの働き方
    プロセスとスレッドの違い
  • 同じプロセスのスレッドは同じメモリ領域を共有しますが、プロセス間は独立しています.
  • 同じプロセスのすべてのスレッドのデータ共有で、プロセス間のデータは独立しています.
  • プライマリラインの変更は、他のスレッドの動作に影響を与える可能性がありますが、親プロセスの変更は、他のプロセスに影響を与えません.
  • 4.スレッドはコンテキストの実行命令であり、プロセスは演算に関連するリソースのクラスタです.
  • 5.同じプロセスのスレッド間で直接通信できますが、プロセス間のコミュニケーションは中間エージェントによって実現される必要があります.
  • 6.新しいスレッドを作成するのは簡単ですが、新しいプロセスを作成するには親プロセスをコピーする必要があります.
  • 7.1つのスレッドは、同じプロセスの他のスレッドを操作できますが、プロセスはサブプロセスのみを操作できます.
  • 8.スレッドの起動速度は速く、プロセスの起動速度は遅い(ただし、両者の実行速度には比べものにならない).

  • Pythonにおけるマルチスレッドの実現
  • 1.関数入力
  • を作成
    import threading
    import time
    
    
    def download_music():
        for i in range(5):
            time.sleep(1)
            print("---      %d---" % i)
    
    
    def play_music():
        for i in range(5):
            time.sleep(1)
            print("---      %d---" % i)
    
    
    def main():
        #         ,target              
        t1 = threading.Thread(target=download_music)
        t2 = threading.Thread(target=play_music)
    
        t1.start()
        t2.start()
    
    
    if __name__ == '__main__':
        main()
    
    # download_music()
    # play_music()
    

    1.マルチスレッド同時処理を使用すると、より短い時間がかかることがわかります.
    2.start()を呼び出すと、スレッドが実際に実行され、スレッド内のコードが実行されます.
  • threadクラスを継承し、run関数に実行するコードを
  • に書き込む新しいclassを作成します.
    pythonのthreading.Threadクラスにはrunメソッドがあり、スレッドの機能関数を定義し、独自のスレッドクラスでメソッドを上書きできます.独自のスレッドインスタンスの後、THreadのstart()メソッドでスレッドを起動できます.このスレッドが実行の機会を得るとrun()メソッドがスレッドを実行するように呼び出されます.
    注意:
    threading.currentThread():          。 
    threading.enumerate():               list。          、   ,             。 
    threading.activeCount():len(threading.enumerate())

    スレッドがいつオープンし、いつ終了するか
  • サブスレッドがいつオープンし、いつ実行されるか
  • threadを呼び出す.start()の場合、スレッドを開き、スレッドのコードを実行します.

  • サブスレッドがいつ終了するか
  • サブスレッドtargetが指す関数の文を実行した後、またはスレッドのrunコードを実行した後、直ちに現在のサブプロセスを終了します.

  • 現在のスレッド数の表示
  • threating.Enumrate()は、現在実行されているすべてのスレッド
  • を列挙することができる.
  • プライマリ・スレッドがいつ終了するか
  • すべてのサブスレッドの実行が完了すると、メインスレッドは
  • に終了します.

    demo: