<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>「並列処理」タグの記事一覧Python Tech</title>
	<atom:link href="https://tech.nkhn37.net/tag/%E4%B8%A6%E5%88%97%E5%87%A6%E7%90%86/feed/" rel="self" type="application/rss+xml" />
	<link>https://tech.nkhn37.net</link>
	<description>Python学習サイト</description>
	<lastBuildDate>Thu, 12 Mar 2026 21:06:11 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://tech.nkhn37.net/wp-content/uploads/2021/01/cropped-lion-normal-clear-1-32x32.png</url>
	<title>「並列処理」タグの記事一覧Python Tech</title>
	<link>https://tech.nkhn37.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【Python】並行・並列処理、I/Oバウンド・CPUバウンドを理解する</title>
		<link>https://tech.nkhn37.net/pythoni-parallel-process-io-cpu-bound/</link>
					<comments>https://tech.nkhn37.net/pythoni-parallel-process-io-cpu-bound/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 03 Feb 2024 20:00:00 +0000</pubDate>
				<category><![CDATA[concurrent.futures]]></category>
		<category><![CDATA[CPUバウンド]]></category>
		<category><![CDATA[I/Oバウンド]]></category>
		<category><![CDATA[threading]]></category>
		<category><![CDATA[マルチプロセス]]></category>
		<category><![CDATA[並列処理]]></category>
		<category><![CDATA[並行処理]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=10199</guid>

					<description><![CDATA[並行処理や並列処理、I/O バウンドや CPU バウンドといった概念と Python におけるマルチスレッド、マルチプロセスとの関係性について解説します。 並行・並列処理と I/O バウンド・CPU バウンド マルチスレ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">並行処理や並列処理、I/O バウンドや CPU バウンドといった概念と Python におけるマルチスレッド、マルチプロセスとの関係性について解説します。</p>



<h2 class="wp-block-heading jinr-heading d--bold">並行・並列処理と I/O バウンド・CPU バウンド</h2>



<p class="wp-block-paragraph">マルチスレッドやマルチプロセスのプログラミングでは「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">並行処理</span></span>」や「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">並列処理</span></span>」、そして「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">I/O バウンド</span></span>」や「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">CPU バウンド</span></span>」といった用語が重要です。これらの概念をしっかりと理解することは、効率的なプログラムを設計するうえで不可欠です。</p>



<p class="wp-block-paragraph">本記事では、これらの概念と Python における<span class="jinr-d--text-color d--marker1 d--bold">マルチスレッド</span>や<span class="jinr-d--text-color d--marker1 d--bold">マルチプロセス</span>のプログラミングとの関連性について説明します。</p>



<h3 class="wp-block-heading jinr-heading d--bold">並行処理と並列処理</h3>



<p class="wp-block-paragraph"><span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">並行処理</span></span>と<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">並列処理</span></span>は、よく混同されがちですが以下のような違いがあります。</p>



<ul class="wp-block-list jinr-list">
<li><strong>並行処理</strong>は、複数タスクが交互に実行され、高速に切り替わることで同時に進行しているように見える処理です。並行処理は、リソースの効率的な使用に焦点を当てています。</li>



<li><strong>並列処理</strong>では、マルチコアプロセッサを活用し、複数タスクが文字通り同時に実行される処理です。並列処理の目的は計算の高速化と処理能力の向上です。</li>
</ul>



<p class="wp-block-paragraph">例えば、OS が複数アプリケーションを管理したり、Web サーバーが複数リクエストを処理したりすることは並行処理の例と言えます。また、科学計算やビッグデータ分析などの高い計算処理速度が求められるタスクでは並列処理が重要な役割を果たします。</p>



<h3 class="wp-block-heading jinr-heading d--bold">I/O バウンドと CPU バウンド</h3>



<p class="wp-block-paragraph">プログラムが直面する可能性のある主要なボトルネックとして「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">I/O バウンド</span></span>」と「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">CPU バウンド</span></span>」という言葉があります。</p>



<ul class="wp-block-list jinr-list">
<li><strong>I/O バウンド</strong>は、入出力操作に時間がかかることを言います。</li>



<li><strong>CPU バウンド</strong>は、計算処理に時間がかかることを言います。</li>
</ul>



<p class="wp-block-paragraph">I/O バウンドは、大量のファイル操作やネットワーク通信を含むタスク、CPU バウンドは、複雑な数学計算やデータ分析が含まれるタスクが該当します。これらのタスクの特性とプログラミング言語の相性を理解することで、パフォーマンスを大幅に向上させることが可能となります。</p>



<h2 class="wp-block-heading jinr-heading d--bold">Python のマルチスレッドとマルチプロセス</h2>



<p class="wp-block-paragraph">Python では、マルチスレッドおよびマルチプロセスで並列処理を実装するためのモジュールが用意されています。マルチスレッドは、<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold"><code>threading</code></span></span> モジュール、マルチプロセスは、<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold"><code>multiprocessing</code></span></span>モジュールが該当します。それぞれの使い方の基本については、以下にまとめているので参考にしてください。</p>



<ul class="wp-block-list jinr-list">
<li><a href="https://tech.nkhn37.net/python-threading-multithread/" target="_blank" rel="noreferrer noopener">threadingによるマルチスレッド処理の基本</a></li>



<li><a href="https://tech.nkhn37.net/python-multiprocessing-basics/" target="_blank" rel="noreferrer noopener">multiprocessingによるマルチプロセスの基本</a></li>
</ul>



<p class="wp-block-paragraph">Python のマルチスレッドやマルチプロセスを理解するには Python 実装と GIL について理解が必要です。Python 実装で最も広く使われている CPython では、マルチスレッドを多くの状況で効果的に使用できない制限が存在し、<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">グローバルインタープリタロック（GIL）</span></span>として知られています。なお、GIL は、CPython 特有のもので、例えば、Java で実装された Jython には存在しません。</p>



<p class="wp-block-paragraph">GIL では、Python オブジェクトにアクセスする処理は、1 つのスレッドに限定されます。そのため、Python で CPU バウンドな処理においてはマルチスレッドを利用しても、スレッドがシリアル化されて順次実行されるため、高速化が難しくなります。</p>



<p class="wp-block-paragraph">この場合は、マルチスレッドではなく、マルチプロセスの利用が有効です。一方で、I/O バウンドな処理や C 拡張のモジュールを使う場合では、GIL の影響は軽減されることがあり、マルチスレッドでも効果を見込むことができます。</p>



<p class="wp-block-paragraph">以降では、簡単な I/O バウンドな処理と CPU バウンドな処理を使って、Python のマルチスレッドとマルチプロセスがどのような違いがでるかを見てみましょう。</p>



<p class="wp-block-paragraph">なお、マルチスレッドとマルチプロセスの実装では、<code>threading</code> や <code>multiprocessing</code> ではなく、より簡単に実装ができる <span class="marker"><span class="jinr-d--text-color d--marker1 d--bold"><code>concurrent.futures</code></span></span> モジュールを使用できます。以降説明では <code>concurrent.futures</code> を使いつつ説明をしていきます。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox6 ">
			<i class="jif jin-ifont-v2books" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p class="wp-block-paragraph"><code>concurrent.futures</code> の使い方の基本は「<a href="https://tech.nkhn37.net/python-concurrent-futures-basics/" target="_blank" rel="noreferrer noopener">concurrent.futuresによる並列処理の基本</a>」を参照してください。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">I/O バウンドなタスク</h3>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">I/O バウンドな処理</span>に対してマルチスレッドとマルチプロセスでどのような違いがあるか以下の例で見てみます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import concurrent.futures
import os
import time


def io_bound_process(file_name, text):
    """IOバウンドな処理を実行する関数"""
    with open(file_name, "w+") as file:
        # ファイルに書き込み
        file.write(text)
        # シーク位置を戻して読み込み
        file.seek(0)
        file.read()

    os.remove(file_name)
    return "io_bound_process done."


def main():
    """メイン"""
    large_text = "test_string" * 10000000

    # 通常の順番でのIO処理
    start = time.time()
    print(io_bound_process("./test1.txt", large_text))
    print(io_bound_process("./test2.txt", large_text))
    end = time.time()
    print(f"順次処理 {end - start:.4f}\n")

    # マルチスレッドで処理
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        start = time.time()
        multi_thread1 = executor.submit(io_bound_process, "./test1.txt", large_text)
        multi_thread2 = executor.submit(io_bound_process, "./test2.txt", large_text)
        print(multi_thread1.result())
        print(multi_thread2.result())
        end = time.time()
        print(f"マルチスレッド {end - start:.5f}\n")

    # マルチプロセスで処理
    with concurrent.futures.ProcessPoolExecutor(max_workers=2) as executor:
        start = time.time()
        multi_process1 = executor.submit(io_bound_process, "./test1.txt", large_text)
        multi_process2 = executor.submit(io_bound_process, "./test2.txt", large_text)
        print(multi_process1.result())
        print(multi_process2.result())
        end = time.time()
        print(f"CPU数: {os.cpu_count()}")
        print(f"マルチプロセス {end - start:.5f}\n")


if __name__ == "__main__":
    main()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果例】
io_bound_process done.
io_bound_process done.
順次処理 1.6407

io_bound_process done.
io_bound_process done.
マルチスレッド 1.19107

io_bound_process done.
io_bound_process done.
CPU数: 16
マルチプロセス 1.39711</pre>



<p class="wp-block-paragraph">上記の <code>io_bound_process</code> 関数では、指定されたファイルへ受け取った文字列を書き込み、その後に読み込んだファイルを消すといった I/O に関わる操作をしています。書き込む文字列は、<code>main</code> 関数で「<code>large_text = "test_string" * 10000000</code>」という長い文字列を作成しています。お使いの PC スペックに合わせて長さは調整してください。</p>



<p class="wp-block-paragraph"><code>main</code> 関数では、<code>io_bound_process</code> 関数を2回呼び出す処理を、1) 順次実行、2) マルチスレッド、3) マルチプロセスで実行し、処理時間を出力しています。なお、マルチスレッド、マルチプロセスでは、<code>max_workers=2</code> で最大 2 並列としています。</p>



<p class="wp-block-paragraph">結果を見てみると、順次実行に対してマルチスレッドもマルチプロセスも処理が速くなっていますが、マルチスレッドの方が効果が大きくなっていることが分かります。</p>



<p class="wp-block-paragraph">マルチスレッドは、メモリ空間を共有するのに対して、マルチプロセスでは各プロセスで独立したメモリ空間を持ち、プロセス間通信が発生することがあるため、オーバーヘッドが発生するため、マルチプロセスの方が遅くなっていると考えられます。</p>



<p class="wp-block-paragraph">マルチスレッドは非常に多くのスレッドを作ることができるのに対して、マルチプロセス数は実行環境の CPU 数に依存します。そのため、I/O バウンドな処理では、マルチプロセスよりもマルチスレッドの方が効果的である場合があり、十分検討する必要があります。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--heading-iconbox1 ">
			<div class="a--heading-iconbox-title">
			<div class="a--iconbox-title-icon"><i class="jif jin-ifont-caution" aria-hidden="true"></i></div>
			<div class="a--iconbox-title-text">注意点</div>
			</div>
			<div class="a--jinr-iconbox">
<p class="wp-block-paragraph">I/O バウンドな処理では、コンピュータの I/O 状況や実行環境に依存する部分があるため、必ずしも上記のような傾向になるとは限りません。<br>I/O の待ち時間を他の処理と重ねられるため、一般的にはマルチスレッドが有利になる場合が多いですが、実行時の状況によってはマルチプロセスや順次処理の方が速い結果となることもあります。</p>
</div>
		</div></section>



<h3 class="wp-block-heading jinr-heading d--bold">CPU バウンドなタスク</h3>



<p class="wp-block-paragraph"><span class="jinr-d--text-color d--marker1 d--bold">CPU バウンドな処理</span>に対してマルチスレッドとマルチプロセスでどのような違いがあるか以下の例で見てみましょう。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import concurrent.futures
import os
import time


def cpu_bound_process():
    """CPUバウンドな処理を実行する関数"""
    i = 0
    while i &lt; 100000000:
        i = i + 1
    return "cpu_bound_process done."


def main():
    """メイン"""
    # 通常の順番でのCPU処理
    start = time.time()
    print(cpu_bound_process())
    print(cpu_bound_process())
    end = time.time()
    print(f"順次処理 {end - start:.4f}\n")

    # マルチスレッドで処理
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        start = time.time()
        multi_thread1 = executor.submit(cpu_bound_process)
        multi_thread2 = executor.submit(cpu_bound_process)
        print(multi_thread1.result())
        print(multi_thread2.result())
        end = time.time()
        print(f"マルチスレッド {end - start:.5f}\n")

    # マルチプロセスで処理
    with concurrent.futures.ProcessPoolExecutor(max_workers=2) as executor:
        start = time.time()
        multi_process1 = executor.submit(cpu_bound_process)
        multi_process2 = executor.submit(cpu_bound_process)
        print(multi_process1.result())
        print(multi_process2.result())
        end = time.time()
        print(f"CPU数: {os.cpu_count()}")
        print(f"マルチプロセス {end - start:.5f}\n")


if __name__ == "__main__":
    main()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果例】
cpu_bound_process done.
cpu_bound_process done.
順次処理 5.4354

cpu_bound_process done.
cpu_bound_process done.
マルチスレッド 5.44025

cpu_bound_process done.
cpu_bound_process done.
CPU数: 16
マルチプロセス 2.86662</pre>



<p class="wp-block-paragraph">上記の　<code>cpu_bound_process</code>　関数は、CPU　バウンドな処理となっています。数値を加算していくだけの非常に単純な計算処理ですが、繰り返し回数を非常に大きな値としています。お使いのPCのスペックに合わせて繰り返し回数は調整してください。</p>



<p class="wp-block-paragraph"><code>main</code> 関数の中では、<code>cpu_bound_process</code> 関数を2回呼び出す処理を、1) 順次実行、2) マルチスレッド、3) マルチプロセスで実行し、処理時間を出力しています。なお、マルチスレッド、マルチプロセスでは、<code>max_worker=2</code> で最大 2 並列としています。</p>



<p class="wp-block-paragraph">結果を見ると、順次実行が遅いのは理解できますが、マルチスレッドでも順次実行とほぼ同じ処理時間となってしまっています。これは、マルチスレッドが CPU バウンドな処理では GIL により結局は順次実行となってしまっているためです。</p>



<p class="wp-block-paragraph">一方で、マルチプロセスでは、明確に処理するコアが異なるため、順次実行に比べて大幅に処理時間が早くなっています。なお、<code>os.cpu_count()</code> で使用環境の CPU 数を確認しています。</p>



<p class="wp-block-paragraph">このように CPU バウンドな処理では、マルチスレッドの効果は出ない可能性があります。CPUバウンドな処理では、マルチプロセスの使用を検討するとよいでしょう。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p class="wp-block-paragraph">「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">並行処理</span></span>」「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">並列処理</span></span>」「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">I/O バウンド</span></span>」「<span class="marker"><span class="jinr-d--text-color d--marker1 d--bold">CPU バウンド</span></span>」といった概念と Python におけるマルチスレッド、マルチプロセスのプログラミングとの関係性について解説しました。</p>



<p class="wp-block-paragraph">並行処理と並列処理は、よく混同されますが厳密には異なる概念です。並行処理は、複数タスクが交互に実行され、高速に切り替わることで同時に進行しているかのように見える処理であるのに対して、並列処理はマルチコアプロセッサを活用して、複数タスクが文字通り同時に実行されます。</p>



<p class="wp-block-paragraph">また、I/O バウンドは入出力操作に時間がかかること、CPU バウンドは計算処理に時間がかかることを意味しており、これらの違いを意識したプログラミングが必要です。</p>



<p class="wp-block-paragraph">今回は、簡単な I/O バウンドな処理と CPU バウンドな処理で、Python のマルチスレッドとマルチプロセスの違いを確認しました。</p>



<p class="wp-block-paragraph">Python では、GIL の影響で CPU バウンドな処理ではマルチスレッドの効果は少なく、マルチプロセスの方が適切な場合があります。一方で、I/O バウンドな処理では、マルチスレッドでも GIL の影響が軽減するため、多くのスレッドで実行が可能なマルチスレッドは、CPU数に依存するマルチプロセスよりも効果的な場合があります。</p>



<p class="wp-block-paragraph">並列処理の実装では、今回紹介したような特徴をよく理解して検討することが非常に重要です。ぜひ、並行処理、並列処理、I/O バウンド、CPU バウンドといった概念と Python におけるマルチスレッド、マルチプロセスの関係性を理解し、効率的に開発できるようになってください。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-libraries/multi" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://tech.nkhn37.net/python-tech-summary-page/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://tech.nkhn37.net/wp-content/uploads/2024/08/Python-Tech-Pythonプログラミングガイド_new1-640x360.jpg" alt="【Python Tech】プログラミングガイド" /></div><div class="a--blogcard-title d--bold">【Python Tech】プログラミングガイド</div></a></section>]]></content:encoded>
					
					<wfw:commentRss>https://tech.nkhn37.net/pythoni-parallel-process-io-cpu-bound/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Disk: Enhanced  を使用したページ キャッシュ

Served from: tech.nkhn37.net @ 2026-06-06 23:56:56 by W3 Total Cache
-->