Edited at

プロセスとスレッドとタスクの違いを知ってUnity非同期完全理解に近付く


最初に

本記事はUnity非同期完全に理解するための序章となります。

すでにタスク、スレッド、プロセスについて理解している方は次の目次から目的の記事を選択して頂ければと思います。

Unity非同期完全に理解するための歩み:

- 【Part0】タスクとスレッドとプロセスの違いを知って非同期完全理解に近付く ←今ココ!

- 【Part1】Unity非同期完全に理解するための第一歩~非同期処理とは何か~

- 【Part2】古来よりUnity非同期を実現していたコルーチンとは何者か?

- 【Part3】非同期理解のためにasync/awaitとTaskの基礎を学んだ話


プロセス

私達が普段起動し使用しているゲームやツール等、それら一つ一つのアプリケーションと、そのアプリケーションに対する「管理情報」をまとめたものプロセスと呼ばれます。OSから見た時には、プロセスが1つの実行単位となります。

プロセス間は同じプログラムを使用していない限りはメモリを共有しません。つまりプロセスの数だけメモリは割り当てられていきます

↓プロセスについてもっと知りたい方はこちら↓

【小ネタ】プロセスってなんだろう?という話


マルチタスク(又はマルチプロセス)

私達は普段からこの機能をスマホやPC等に搭載されているOSで使用しています。この機能があるおかげで、コンパイルを行いながらネットを見たり、音楽を聴きながらTwitterするような複数プロセスの同時実行が可能なのです。

ところでCPUは1コアに対して一度に1つのプロセスしか実行できません。ではどうやってマルチタスクを実現しているのでしょうか。

答えは難しくありません。マルチタスク機能によって複数のプロセスを細かく切り替えることで同時に動いているように見せているのです。


スレッド

スレッドとはプロセス内に作られる並列動作が可能な処理の単位です。

シングルスレッドなら1プロセスに1スレッド、マルチスレッドなら1プロセスで複数のスレッドが動作しています。

スレッドはプロセスに割り当てられたメモリを使用して動作しています。スレッド同士ではメモリを共有しているため、メモリの切り替えも含めたプロセスの切り替えに比べると、スレッドの切り替えは高速に動きます。ただし、メモリを共有しているということは、ほとんどのデータをスレッド同士で共有しているということで、同じ変数に対してスレッド同士が同時に値を書き換えようとする場合に開発者側が意図していない状況になることが殆どです。なので、マルチスレッドプログラムを開発するのであれば、このような問題が起きない(スレッドセーフ)ようなプログラムを意識する必要があります。


Unityでは、私達がゲームのメインに当たるプログラムを記述した際に、そのプログラムを実行するスレッドがメインスレッドとなっています。もちろんゲームのメイン処理と同時に実行するスレッドを追加で作成することが可能です。

ただし、メインスレッドからはUnityのAPIを叩くことが可能ですが、それ以外のユーザーが作成したスレッドでは、UnityのAPIへアクセスができません。なので、別スレッドには計算系の処理を任せ、その結果を用いた処理をメインスレッドで行うような用途がちょうどいいかと思われます。最近のUnityにはC# Job Systemというマルチスレッドプログラミングのハードルをより下げてくれる機能が備わっているので是非一度確認してみてください。

「Unity2018.xで知っておきたいC# Job System機能の概要」

【CEDEC2017】C#JobSystem を使った Unity流マルチスレッドプログラミング

↓スレッドについてもっと知りたい方はこちら↓

【小ネタ】スレッドってなんだろう?という話


タスク

さて、タスクに関してですが、タスクという言葉は曖昧です。タスクという言葉は以下の意味を持つことがあります。


  1. プロセスと同じ意味で使われる。

  2. スレッドのことを指す。

  3. スレッドに割り当てられ、非同期に呼び出される実行単位。

C#ではタスクは⑶の意味を持つと思われます(async/awaitと結びつくTaskクラス)。タスクに基づいた並行処理では、タスクとスレッドは明示的に別々に管理されます。この場合のタスクはスレッド上で実行されるため、スレッドが持つ強みと弱みを共有します。

タスクとよく似た用語として「ジョブ」という言葉もあります。

ジョブはUnityにおけるC# Job Systemでは並列処理として、別スレッドにお願いする処理の単位を指します。


参考