【Python / ソケット通信】マルチプロセッシングでサーバーの処理を並列化

サーバーの処理の並列化手法の説明ページのアイキャッチ

このページにはプロモーションが含まれています

このページでは、マルチプロセッシングを利用してソケット通信を行うサーバーの処理の並列化を実現していきたいと思います。言語としては Python を利用します。

サーバーの処理を並列化すると何が嬉しい?

まず、なぜサーバーの処理を並列化すると嬉しいのか?という点について説明していきます。

サーバーやクライアントの意味合いについては下記ページで解説していますが、サーバーはサービスを提供するプログラムであり、クライアントはサーバーに対してリクエストを送信してサービスを利用するプログラムとなります。

Pythonでのソケット通信(ポート番号・プロトコル・サーバー / クライアント)

並列化されていないとレスポンス速度が低下

サーバーはクライアントからのリクエスト(何らかの要求)を受け取ると、サーバーが提供するサービス&リクエストの内容に応じた処理を行い、その結果をレスポンスとしてクライアントに対して返却するような作りになっていることが多いです。

サーバーの説明図

また、このサーバーとクライアントの関係において、サーバーとクライアントの数的な関係は1対多、もしくは少数対多数という関係になります。要は、サーバーの数に比べてクライアントの数の方が多いということになります。

サーバーが複数のクライアントを相手に通信する様子

なので、サーバーは多数のクライアントから同時にリクエストを受け取る可能性があります。その時に、処理が並列化されていないサーバーの場合、基本的には同時に受け取ったリクエストを1つ1つ逐次的に処理していくことになります。つまり、この場合、サーバーは同時に1つの処理しか実行できません

そのため、この場合は特定のクライアントからのリクエストを処理している間、他のクライアントからリクエストを受け取ることもできないですし、他のクライアントに対してレスポンスが返却できないことになります。こうなると、サーバーに対してリクエストを送信しても応答がないため、クライアントを利用しているユーザーはサーバーに対して「レスポンスが遅い」という印象を持ち、せっかく画期的なサービスを開発したとしても、ユーザーからは使いにくいサービスと評価されて人気がなくなってしまう可能性があります…。

クライアントがサーバーに待たされる様子

スポンサーリンク

並列化によってレスポンス速度が向上!

この問題を解決する1つの手段が並列化となります。

並列化を取り入れれば、プログラムは同時に1つのみの処理だけでなく、複数の処理を同時に実行できるようになります。

複数の処理を同時に実行する様子

したがって、サーバーの処理を並列化しておけば、特定のクライアントからのリクエストを受け付けて処理を行っている間も、他のクライアントからのリクエストの受け付けや、そのリクエストに対する処理を並列的に同時に実行することが可能となります。

そのため、複数のクライアントが同じサーバーに同時にリクエストを送信した場合でも、それらのクライアントが待たされることが減ります。

このようにサーバーの処理を並列化をしておくことで、クライアントへのレスポンス速度を向上させ、ノンストレスで使い勝手の良いサービスを提供することができるようになります。

サーバーが3つのクライアントと並列的に通信を行なっている様子

処理が並列化されていないサーバーの動作確認

実際に、処理が並列化されていないサーバーの Python スクリプトを実行し、複数のクライアントからリクエストを受け付けたときにどのような動作になるのかを確認していきたいと思います。

並列化されていないサーバーのスクリプト

まず、今回動作確認に使用する「処理が並列化されていないサーバー」のスクリプトの例は下記となります。

no_parallel_server.py
import socket
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.bind(('0.0.0.0', 40001))

sock.listen(5)

# 無限ループで常駐させる
while True:

    # 接続要求の受付 / 接続の確立
    e_sock, addr = sock.accept()

    accepted_time = time.time()
    print(f'{accepted_time}:{addr}からの接続要求受付完了')

    # データの受信待ち
    data = e_sock.recv(1024)
    
    # サービス・受信データに応じた処理
    str_data = data.decode()
    upper_str_data = str_data.upper()

    # 10秒間待ち
    time.sleep(10)

    # 処理結果の送信
    send_data = upper_str_data.encode()
    e_sock.send(send_data)

    responded_time = time.time()
    print(f'{responded_time}:{addr}へのレスポンスの返却完了')
   
    e_sock.close()

sock.close()

このスクリプトは TCP 通信を行うサーバーで、クライアントから受信した文字列を大文字に変換するサービスを提供するサーバーとなっています。ちょうど、下記ページの TCP 通信のサーバー の節で紹介したものをベースとした、非常に簡単なサーバーの例となります。

Pythonでのソケット通信(ポート番号・プロトコル・サーバー / クライアント)

ただし、上記ページの TCP 通信のサーバー に対して、ところどころ print で時刻(time.time() の返却値)を出力するようにし、さらに send メソッドを実行する前に time.sleep(10)10 秒間スリープするようにしています。このスリープは、サーバーの処理に時間がかかることを模擬するために実行しています。サーバーの処理に 10 秒かかるようなケースは少ないと思いますが、極端に長い時間スリープさせた方が並列化するメリットが感じやすいと思います。

スポンサーリンク

動作確認用のクライアントのスクリプト

次に、先ほど示したサーバーの通信相手となるクライアントのスクリプト例を示します。そのスクリプトが下記になります。

client.py
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

input_str_data = input('文字列を入力してください : ')


# 接続要求の送信
address = ('127.0.0.1', 40001)
sock.connect(address)

# データの送信
data = input_str_data.encode()
sock.send(data)

# データの受信
data = sock.recv(1024)
str_data = data.decode()

print(str_data)

sock.close()

これは下記ページの TCP 通信のクライアント の節で紹介したスクリプトと同じクライアントの例となりますので、詳細な解説が読みたい方は下記ページの TCP 通信のクライアント を参照していただければと思います。

Pythonでのソケット通信(ポート番号・プロトコル・サーバー / クライアント)

並列化されていないサーバーの動作確認

次に 並列化されていないサーバーのスクリプト動作確認用のクライアントのスクリプト を使って処理が並列化されていないサーバーの動作の確認を行っていきます。

まず、並列化されていないサーバーのスクリプト で紹介したスクリプトを no_parallel_server.py というファイル名で、 動作確認用のクライアントのスクリプト で紹介したスクリプトを client.py というファイル名で、適当なフォルダに保存してください。

続いて、ターミナルアプリ(Windows の場合はコマンドプロンプトや Power Shell など)を5つ開き、この5つ全てのターミナルアプリで、先ほどスクリプトをファイル保存したフォルダに移動してください。

この5つのターミナルアプリのうち、1つは no_parallel_server.py 実行用で、残りの4つは client.py 実行用として利用します。4つの client.py を実行することで、複数のクライアントからサーバーがリクエストを受け付ける動作を模擬していきます。

各ターミナルで実行するプログラムの説明図

ということで、フォルダを移動したら、1つ目のターミナルアプリで下記のコマンドを実行してサーバーを起動します。

python no_parallel_server.py

ここからは、出来るだけ素早くアプリの操作とコマンドの実行を行っていく必要があるので注意してください。何度でもやり直せるので、失敗したらやり直していただければ良いですし、ここに記載されている結果だけ確認していただくのでも別に良いです。

では、つづいて、2つ目のターミナルアプリで下記のコマンドを実行します。これによりクライアントが起動し、最初に文字列の入力が促されるので、ここで適当な英数字を入力してください。

python client.py
文字列を入力してください : a

同様に、次は3つ目のターミナルアプリでも同じコマンド実行を行います。入力する文字列は、先ほど入力したものとは異なるものにしてください。

python client.py
文字列を入力してください : b

これと同じことを、4つ目と5つ目のターミナルアプリでも行います。そして5つ目のターミナルアプリで入力した文字列を大文字に変換した結果が出力されるまでしばらく待ってください。

5つ目のターミナルアプリに大文字に変換した結果が出力されたら、1つ目のターミナルアプリに出力されている時刻や文字列、つまりサーバーの出力結果に注目してみましょう。

私の場合、サーバーが出力した文字列は下記のようになっていました。各クライアントを起動するタイミング等によって結果は異なるものの、「先に接続要求を送信してきたクライアントへのレスポンスを返却しないと次のクライアントの接続要求の受付が行われない」という点は確認できるのではないかと思います。ちなみに、括弧内の2つ目の数値がクライアント側のソケットに関連付けられたポート番号になります。

1722293212.764506:('127.0.0.1', 58620)からの接続要求受付完了
1722293222.7732816:('127.0.0.1', 58620)へのレスポンスの返却完了
1722293222.7732816:('127.0.0.1', 58622)からの接続要求受付完了
1722293232.7745848:('127.0.0.1', 58622)へのレスポンスの返却完了
1722293232.7948654:('127.0.0.1', 58624)からの接続要求受付完了
1722293242.80623:('127.0.0.1', 58624)へのレスポンスの返却完了
1722293242.814341:('127.0.0.1', 58626)からの接続要求受付完了
1722293252.8232408:('127.0.0.1', 58626)へのレスポンスの返却完了

つまり、先に connect メソッドによって接続要求を送信してきたクライアントに対して accept を行った後に recv メソッド〜 close メソッドを実行している間、次に接続要求を送信してきたクライアントに対する accept は実行されません。

サーバーが特定のクライアントとの間で通信を行なっている間、他のクライアントの通信が待たされてしまう様子

なので、クライアントはサーバーで accept が実行されるのを待つことになりますし、それに伴い、その後のサーバーでの recv メソッド以降の処理も遅れて実行されることになります。

そのため、下の図のように、複数のクライアントから同時にリクエストが送信されてきた場合に、最初に accept した接続要求を送信してきたクライアントを除き、他のクライアントを待たせてしまうことになります。

クライアントBとの通信がサーバーによって待たされてしまう様子をシーケンスで表した図

もちろん、今回はサーバー側で sleep10 秒実行していて処理時間が長いので、クライアントが待たされる時間も極端に長くなってしまっています。ですが、どんなサーバーでも処理時間は 0 ではないですし、クライアント側の状況によってデータの送受信に時間がかかる可能性もあるため、あらゆるサーバーで上記のような処理が起こりうると考えて良いです。

ここからは、上記のようなクライアントが待たされる問題の解決策について解説していきます。

サーバーの処理の並列化

ここまで説明してきたように、同時に複数のクライアントがリクエストを送信してきたときにクライアントが待たされてしまう問題の要因の1つは「サーバーが逐次的にしか処理が実行できない」という点にあります。

スポンサーリンク

処理の並列化の考え方

なので、逐次的ではなく、並列的に処理を行うようにすることで、上記のような問題を解決することができます。少なくとも、この待たされる時間をを軽減することが可能です。

この並列化を行う方法はたくさん存在するのですが、このページではマルチプロセッシングという技術を使ってサーバーの処理の並列化を行っていきたいと思います。

マルチプロセッシングとは、簡単に言うとプロセスを複数に分割する技術のことを言います。通常、プログラムは単一のプロセスとして動作するのですが、プログラム内の特定の処理(関数・メソッド)を別のプロセスに分離してやれば、プログラムが複数のプロセスとして実行されることになります。さらに、思い切って細かい説明は省略しますが、複数のプロセスが存在すれば、それらの複数のプロセスは別々の CPU コアによって並列的に同時に実行されることになります。

今回は、 並列化されていないサーバーのスクリプト で紹介したスクリプトにおいて、recv メソッド~ close メソッドの処理の部分を切り離して別の関数として定義し、この関数が accept とは別のプロセスとして処理されるようにします(この関数の関数名は service であるとして説明していきます)。

処理の一部を別のプロセスとして実行するようにした様子

これにより、特に while ループ内の処理で考えれば、accept を実行するプロセスと service を実行するプロセスが別のプロセスとして存在することになり、これらが別々のCPU コアによって並列的に、かつ同時に実行されることになります。

プロセスを分けたことで複数のCPUコアで処理が実行されるようになった様子

さらに、accept を実行するたびに service を実行するプロセスを新規で生成するようにしてやれば、もともと存在している accept を実行するプロセスに加えて “通信相手となるクライアントの数だけのプロセス” が存在することになり、各プロセスが別々のコアによって実行されるため、理想的にはクライアントが待たされることが無くなります。

acceptするたびにプロセスを生成する様子

ただ、結局は CPU コアによってプロセスは処理されることになり、CPU コアの数は有限であるため、いずれは CPU コアの数が足りなくなり、サーバーが相手するクライアントが多くなるとクライアントは結局待たされることになります。ですが、それでも逐次的に各クライアントに対するリクエストを処理するよりかは、トータルで考えればクライアントに対するレスポンスが向上することになります。

ということで、詳細な説明に関しては省略させていただきましたが、とりあえずマルチプロセッシングを利用してプログラムを複数プロセスで処理させることで “処理の並列化” を実現可能であることは理解していただけたのではないかと思います。

処理の並列化の手順

次は、具体的な並列化の手順を説明していきます。

mutliprocessing モジュールの import

まず、このマルチプロセッシングは mutliprocessing モジュールによって提供される仕組みであるため、事前に multiprocessing モジュールを import しておく必要があります。この multiprocessing モジュールは Python の標準モジュールとなっているため、Python が利用できれば multiprocessing モジュールも利用可能なはずです。

multiprocessing
import multiprocessing

並列化したい処理の関数化

続いて、別のプロセスで実行したい処理を関数化します。要は、元々のプログラムと並列に実行したい処理を1つの関数にまとめます。

今回は、while ループ内の処理における recv メソッド~ close メソッドの部分を別のプロセスで実行できるよう、これらの実行部分を関数化します。

そのために、まずは 並列化されていないサーバーのスクリプト で示したスクリプトの while ループ内の処理における recv メソッド~ close メソッドを実行している部分を削除し、

関数化1
# 無限ループで常駐させる
while True:

    # 接続要求の受付 / 接続の確立
    e_sock, addr = sock.accept()

    accepted_time = time.time()
    print(f'{accepted_time}:{addr}からの接続要求受付完了')

続いて、service 関数を新たに定義し、先ほど削除した部分をそのまま service 関数内に記述します。recv メソッド~ close メソッドを実行するためには、accept メソッドの返却値である e_sock (接続確立後のソケット) と addr (接続確立先のクライアントの情報) が必要になるため、それらを引数として受け取るようにしています。今回の例の場合、addr に関しては print するために利用するだけなので実処理には必要ではありませんが、e_sockrecvsend を実行するために必須となります。

関数化2
def service(e_sock, addr):
    # データの受信待ち
    data = e_sock.recv(1024)

    # サービス・受信データに応じた処理
    str_data = data.decode()
    upper_str_data = str_data.upper()

    # 10秒間待ち
    time.sleep(10)

    # 処理結果の送信
    send_data = upper_str_data.encode()
    e_sock.send(send_data)

    responded_time = time.time()
    print(f'{responded_time}:{addr}へのレスポンスの返却完了')

    e_sock.close()

プロセスの生成

続いて、並列化を実現するためにプロセスの生成を行います。このプロセスの生成は multiprocessing モジュールの Process クラスのインスタンスの生成および、そのインスタンスでの start メソッドの実行により実現できます。

まず、Process クラスのインスタンス生成について説明すると、このインスタンスは Process クラスのコンストラクタ、すなわち multiprocessing.Process() を実行することで生成できます。さらに、この multiprocessing.Process()target 引数に、その生成されるプロセスで実行したい関数やメソッドのオブジェクトを指定します。さらに、args 引数や kwargs 引数で、その target 引数に指定した関数に渡したい引数を指定します。args 引数の場合はイテラブルなオブジェクト、kwargs 引数には辞書等を指定します。位置引数を指定するのであれば args、キーワード引数を指定するのであれば kwargs を指定すれば良いですし、両方指定するようなことも可能です。

Process()の実行
process = multiprocessing.Process(
    target=関数, # 生成するプロセスで実行する関数
    args=リストやタプル, # 関数に渡す位置引数
    kwargs=辞書 # 関数に渡すキーワード引数
)

そして、Process クラスのインスタンスである multiprocessing.Process() の返却値に start メソッドを実行させれば、args 引数や kwargs 引数で指定したデータが引数として渡された状態で target 引数で指定した関数が実行されるプロセスが生成されることになります。そして、そのプロセスが CPU コアによって実行されることになります。

startメソッドの実行によってプロセスが生成され、CPUコアによってプロセスが実行される様子

今回は、while ループ内の accept メソッド実行後にプロセスの生成を行います。そして、ここで生成するプロセスで実行する関数は先ほど作成した service 関数とし、さらに service 関数には accept メソッドの返却値である e_sockaddr を引数として渡すため、while ループ内の処理を下記のように変更することになります。 

プロセスの生成
# 無限ループで常駐させる
while True:

    # 接続要求の受付 / 接続の確立
    e_sock, addr = sock.accept()

    accepted_time = time.time()
    print(f'{accepted_time}:{addr}からの接続要求受付完了')

    # プロセスの生成
    process = multiprocessing.Process(
        target=service,
        kwargs={'e_sock':e_sock, 'addr':addr}
    )
    process.start()

このように処理を変更すれば、accept メソッドによってクライアントからの接続要求を受け付けた後に、multiprocessing.Process()start メソッドが実行されて新たなプロセスが生成されることになります。さらに、start メソッドはプロセスを生成のみを行って終了しますので、すぐに while ループ先頭の accept が実行されることになり、次のクライアントからの接続要求をすぐに受け付けることが可能となります。

プロセスを分割することでacceptが常に実行されている状態になることを示す図

並行して、start メソッドが実行されることでプロセスが生成され、service 関数が実行されることになり、プロセス生成前に接続要求を受け付けたクライアントとの間でデータの送受信が recv メソッドや send メソッドにより行われることになります。

また、service 関数の処理が終了したら、生成されたプロセスは終了して消滅することになります。

マルチプロセッシングを利用せずに単に service 関数を呼び出すようにしてしまうと、service 関数が終了するまで、すなわち recv メソッド~ close メソッドまでの間 acceptが実行されないことになってクライアントが待たされてしまいますが、マルチプロセッシングを利用すれば acceptservice 関数の実行を並列に実行することが可能となります。

サーバーの処理を並列化したプログラム

先ほどは並列化を行うためにポイントとなる変更部分のみのコードを紹介しましたが、ここでプログラム全体のスクリプトを紹介しておきたいと思います。

スポンサーリンク

処理の並列化を行ったスクリプト

サーバーの処理を並列化したプログラムのスクリプト例は下記のようになります。

parallel_server.py
import socket
import time
import multiprocessing

def service(e_sock, addr):
    # データの受信待ち
    data = e_sock.recv(1024)
    
    # サービス・受信データに応じた処理
    str_data = data.decode()
    upper_str_data = str_data.upper()

    # 10秒間待ち
    time.sleep(10)

    # 処理結果の送信
    send_data = upper_str_data.encode()
    e_sock.send(send_data)

    responded_time = time.time()
    print(f'{responded_time}:{addr}へのレスポンスの返却完了')
   
    e_sock.close()

if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    sock.bind(('0.0.0.0', 40001))

    sock.listen(5)

    # 無限ループで常駐させる
    while True:

        # 接続要求の受付 / 接続の確立
        e_sock, addr = sock.accept()

        accepted_time = time.time()
        print(f'{accepted_time}:{addr}からの接続要求受付完了')

        process = multiprocessing.Process(
            target=service,
            kwargs={'e_sock':e_sock, 'addr':addr}
        )
        
        process.start()

    sock.close()

スクリプトの解説

上記スクリプトのポイントを説明しておきます。

処理の並列化の手順 で説明したように、accept が終了してクライアントと接続が確立されたタイミングで新たなプロセスを起動し、そのプロセスで service 関数が実行されることになります。

また、 上記スクリプトでは、ソケットを生成や while ループ等の各処理が __name__ == '__main__' が成立する場合しか実行されないようになっている点もポイントになります。__name__ == '__main__' の意味合いに関しては下記ページで説明しているので詳しく知りたい方は下記ページを参照していただければと思いますが、__name__ == '__main__' が成立する場合しか各処理が実行されないようになっているのは import 時にそれらの処理が実行されないようにするためです。

if __name__ == '__main__'の意味合いの解説ページアイキャッチ 【Python】if __name__ == ‘__main__’ とは

どうも、プロセスを生成する時には import と同様の処理が行われてスクリプトが再読み込みされるようで、その時にソケット生成や bind が行われると余分にソケットが生成されたり例外が発生することになるので、各処理は __name__ == '__main__' が成立する場合のみ、つまり、直接このスクリプトが実行された時のみ行われるようにしています。

こういった注意点等もあるのですが、基本的には multiprocessing.Process() でのインスタンス生成と start メソッドの実行を行えば良いだけなので、簡単に処理の並列化が可能であることは感じ取っていただけるのではないかと思います。

ただし、実は処理の配列化を行う際には排他制御や同期制御などが必要になることが多く、これらの制御が必要になると一気にプログラミングの難易度が上がります。今回は、これらの制御が特に必要ないので簡単に処理が並列化を行うことができていますが、こういった制御が必要になる場合は注意が必要です。

また、生成するプロセスの数にも注意が必要です。上記の場合、accept が終了するたびにプロセスが生成されることになるため、クライアントからの接続要求が同時に大量に送信されてくると、その分生成されるプロセスの数も多くなります。そして、PC の CPU コアの数を上回る数のプロセスが生成されると処理量に対して CPU の仕事が間に合わなくなり、PC の処理が極端に重くなることになります。今回は、listen メソッドの引数で同時に受信可能な接続要求数を制限しているので問題ないと思いますが、実戦で処理の並列化を行う際はこのあたりも頭に入れて設計等を行うようにしましょう!

処理を並列化したサーバーの動作確認

最後に、処理を並列化したサーバーの動作確認を行っていきます。

ここでは、サーバーとして 処理の並列化を行ったスクリプト で紹介したスクリプトを利用し、クライアントとしては 並列化されていないサーバーの動作確認 での動作確認時と同様に、 動作確認用のクライアントのスクリプト で紹介スクリプトを利用します。

動作確認手順は 並列化されていないサーバーの動作確認 と同様で、まずサーバーを起動し、手際よく複数のクライアント(4つのクライアント)を起動して各クライアントに対して文字列を入力し、連続的に複数のクライアントからサーバーに対してリクエストを送信します。

それにより、サーバーを起動しているターミナルに時刻と文字列が出力されるので、それを確認してみましょう!私が試したところ、下記のような出力結果が得られました。

1722504235.7295523:('127.0.0.1', 63494)からの接続要求受付完了
1722504237.7655413:('127.0.0.1', 63497)からの接続要求受付完了
1722504241.0729225:('127.0.0.1', 63499)からの接続要求受付完了
1722504242.8379776:('127.0.0.1', 63502)からの接続要求受付完了
1722504245.9958396:('127.0.0.1', 63494)へのレスポンスの返却完了
1722504247.9743876:('127.0.0.1', 63497)へのレスポンスの返却完了
1722504251.2884297:('127.0.0.1', 63499)へのレスポンスの返却完了
1722504253.0687761:('127.0.0.1', 63502)へのレスポンスの返却完了

並列化されていないサーバーの動作確認 でのサーバーの出力結果と見比べていただければ並列化の効果が確認できると思います。

また、今回のサーバーやクライアントの処理の流れをシーケンス図で表すと下の図のようになります。

各クライアントとの通信が並列的に同時に実行される様子

並列化されていないサーバーの動作確認 で利用したサーバーは処理を逐次的にしか実行できないため、特定のクライアントからの接続要求を受け付けてからレスポンスを返却するまでの間、他のクライアントからの接続要求の受付を行うことができず、その間クライアントが待たされてしまうという問題がありました。なので、複数のクライアントから接続要求が連続的に送信されてきたとしても、必ず特定のクライアントに対する「レスポンスの返却完了」が出力されてから次のクライアントに対する「接続要求受付完了」が出力されるようになっています。

ですが、今回利用したサーバーの場合、前のクライアントに対する処理を実行中でも次のクライアントの接続要求を受け取り、そのクライアントに対する処理を並列的に実行できるようになっています。そのため、複数のクライアントから接続要求が連続的に送信されてきた場合でも、クライアントが待たされることなくすぐに接続要求の受付が行われるようになっています。この結果、クライアントのユーザーからはレスポンスの早いサーバーという印象を持たせることができます。

サーバーの処理の並列化により使いやすいサービスが提供可能になることを示す図

スポンサーリンク

まとめ

このページでは、マルチプロセッシングを利用したサーバーの処理の並列化について解説しました!

サーバーは複数のクライアントを相手にするため、複数のクライアントからのリクエストを並列的に処理できるようにしておくことが重要です。でなければ、複数のクライアントから同時にリクエストを受け取ったような場合にクライアントが待たされることになり、レスポンス性能の悪いサーバーであるとユーザーに印象を持たれてしまう可能性が高いです。

で、処理の並列化自体はマルチプロセッシングを利用すれば簡単に実現可能です。処理の並列化を行うことで、プログラムの処理速度を向上させたり、同時に異なる複数の処理を実行させるようなことも可能になり、これを使いこなせば今まで実現できなかったこともプログラムで実現できるようになります!

もし、多数のクライアントと同時に通信を行うようなサーバーを開発するのであれば、今回説明した処理の並列化の採用を是非検討してみてください!

同じカテゴリのページ一覧を表示