Select Language

AI Technology Community

8.10、Python osモジュールの使用方法の詳細

本章の最後に、osモジュールにおけるプロセスに関するいくつかのインターフェース関数を紹介します。これまでに、このモジュールのいくつかのインターフェース関数、例えば現在のプロセスのPIDを取得する関数などを使用してきました。これらのインターフェース関数は比較的基礎的で、あまり複雑でない環境でも非常に有用です。

もしプロセスの高度な機能を使用する必要がある場合は、multiprocessingモジュールまたはsubprocessモジュールの使用をおすすめします。

1) system():プロセスを起動する

system()インターフェース関数を使用してプロセスを起動することができます。形式は以下の通りです:

os.system(コマンド文字列)

system()インターフェース関数は文字列形式のコマンドを受け取り、そのコマンドを実行するためのプロセスを起動します。そして、そのコマンドが返るまで、このインターフェース関数は返りません。この関数の戻り値は、そのコマンドの戻りコードです。

これはおそらく最もよく使われるインターフェース関数で、任意の実行可能ファイルやスクリプトを実行するために使用することができます。注意点として、引数は文字列で、つまりシェルで入力する内容です。

>>> os.system("date")           # dateはコマンド
Mon Jul  1 15:23:27 CST 2019    # これはdateコマンドの出力
0                               # これはsystem()の戻り値、つまりdateコマンドの戻りコード

コマンド行文字列に引数を付けることができます。例えば以下のような使い方があります:

>>> os.system("echo hello python")
hello python
0

リダイレクト記号やパイプなども使用することができます。例えば以下のような使い方があります:

>>> os.system("ps | grep grep")
23645 ttys006    0:00.00 sh -c ps | grep grep
23647 ttys006    0:00.00 grep grep     
0                                             #これはコマンドの戻りコード、0は成功を意味する

要するに、シェルで実行できる任意のコマンドは、この方法で実行することができます。

2) popen():プロセスを起動して出力を取得する

system()インターフェース関数では、子プロセスの戻りコードしか取得できず、子プロセスの出力を取得することはできません。子プロセスの出力情報を取得したい場合は、open()インターフェース関数を使用することができます。このインターフェース関数の定義は以下の通りです:

os.popen(コマンド行引数文字列)

popen()を使用することで、標準出力情報を取得する問題を解決することができますが、子プロセスの戻りコードは取得できません。以下の例では、子プロセスの標準出力を取得する方法を示しています。

>>> r = os.popen("date", "r", 1)        # 2番目の引数rは読み取り専用を意味する
>>> stdout = r.read()                   # 子プロセスの出力を読み取る
>>> stdout                              # 出力を確認する
'Mon Jul  1 21:55:27 CST 2019\n'        # これがdateコマンドの出力です

子プロセスに入力を提供したい場合は、2番目の引数をwに変更することができます。つまり、この子プロセスにいくつかの情報を書き込むことができます。

以下の例では、コマンドcat - | grep python > a.txtを使用しています。このコマンドの意味は、標準入力からデータを読み取り、grepを使用してpythonを含むすべての行を取得し、そのような行をファイルa.txtに書き込むことです。

# このコマンドを構築する
>>> w = os.popen("cat - | grep python > a.txt", "w", 1)  # cat -コマンドに1行を入力する、最後の\nは改行記号を意味する
>>> w.write("line1: abcd\n")
                              # 書き込まれたバイト数
>>> w.write("line2: love python\n")    # cat -コマンドに別の行を入力する
                              # 書き込まれたバイト数
>>> w.close()                          # wを閉じる、Ctrl+Dキーの組み合わせを押すのと同じ
>>> fd = open('a.txt', 'r')            # ファイルa.txtを開く、つまりコマンドの出力
>>> fd.read()                          # ファイルの内容を読み取る
'line2: love python\n'                 # 2行目がa.txtに保存されます
>>> fd.close()                         # a.txtを閉じる

3) getpid():現在のプロセスIDを取得する

この関数の定義は以下の通りです:

os.getpid()

この関数は、現在のPythonインタープリターのプロセスIDを返します。

>>> os.getpid()                        # 現在のPythonインタープリターのプロセスIDを取得する
21028
>>> os.system("ps | grep python")      # psコマンドを使用してPython関連のプロセスを取得する
21028 ttys006    0:00.17 python3       # これが現在のPythonインタープリターに対応するプロセスです
24741 ttys006    0:00.00 grep python
25399 ttys006    0:00.00 sh -c ps | grep python
25401 ttys006    0:00.00 grep python

4) getppid():親プロセスIDを取得する

この関数は、現在のPythonインタープリターの親プロセスIDを返します。

>>> os.getppid()               # 現在のPythonインタープリターの親プロセスを取得する、つまりbashプロセス
15747
>>> os.system("ps a | grep bash")      # psを使用して関連するbashプロセスを確認する
15747 s006  S      0:00.11 -bash       # これが現在のPythonインタープリターの親プロセスです
25427 s006  S+     0:00.00 sh -c ps a | grep bash
25429 s006  S+     0:00.00 grep bash

これらのインターフェース関数以外にも、LinuxまたはmacOS版のPythonでは、他のプロセス関連のインターフェース関数、例えばfork()、kill()、execv()などが提供されています。これらはC言語版のプロセス操作インターフェース関数に似ていますが、UNIX系のシステムでのみ存在します。したがって、これらのインターフェース関数はWindowsプラットフォームでは存在せず、ここでは説明しません。


post
  • 10

    item of content
プロセスはリソースを分配する単位であり、スレッドはオペレーティングシステムがスケジューリングできる最小の単位です。
通常、プロセスには少なくとも1つのスレッドが含まれ、複数のスレッドがある場合はその中にメインスレッドが含まれます。同じプロセス内のすべてのスレッドはシステムリソースを共有しますが、それぞれが独立したスタック、レジスタ環境、およびローカルストレージを持っています。
マルチスレッドの利点は、複数のタスクを同時に実行できることです。システムに複数の計算ユニットがある場合、複数のスレッドはそれぞれの計算ユニットで並行して動作することができ、これによりシステムの処理効率が大幅に向上します。
多くの場合、プロセスはスレッドよりも大きい単位であり、通常1つのプロセスは複数のスレッドを含むことができます。プロセスの隔離効果はスレッドよりも優れているため、マルチプロセスを使用するとマルチスレッドよりも安全です。ただし、マルチプロセスの欠点はマルチスレッドよりもスケジューリングが重く、効率が低いことです。