python並列処理入門とすねかじりシミュレーション

#初めに
この記事は`python`並列処理の入門と二つ簡単な実例を使って説明していきますがpythonの基礎文法ある程度事前に習得する必要があります
**流れは下記のようになります**

- 並列処理簡単な紹介
    - 簡単な実例
    - すねかじりシミュレーション
    - まとめ
    
     
##並列処理簡単な紹介

一言で言えばプログラムの処理速度上げます

####では簡単な実例を見てみましょう

```python:qiita.py
import time
from datetime import datetime

def coding():
    for x in range(3):
        print("coding%s" % x)
        print(datetime.now())
       """見やすくするためtime.sleepを入れ"""
        time.sleep(1)

def drawing():
    for x in range(3):
        print(datetime.now())
        print('drawing%s' % x)
        time.sleep(1)

def main():
    """一般処理"""
     coding()
     drawing()

if __name__ == "__main__":
    main()
```
二つの関数を順番ごとに実行させて見ると

`coding0
2019-01-22 15:35:48.501081
coding1
2019-01-22 15:35:49.501989
coding2
2019-01-22 15:35:50.502478
drawing0
2019-01-22 15:35:51.502682
drawing1
2019-01-22 15:35:52.503367
drawing2
2019-01-22 15:35:53.504151`

このような結果が出てきます、実行終了までに`5.003070000000001`秒使いました
**また並列処理を入れて同じ処理を実行してみましょう**

```python:qiita.py

"""threadingモジュールを追加インポートします"""
import threading
import time
from datetime import datetime

def coding():
    for x in range(3):
        print("coding%s" % x)
        print(datetime.now())
       """見やすくするためtime.sleepを入れ"""
        time.sleep(1)

def drawing():
    for x in range(3):
        print(datetime.now())
        print('drawing%s' % x)
        time.sleep(1)

def main():
   """並列処理"""
    t1 = threading.Thread(target=coding)
    t2 = threading.Thread(target=drawing)
    t1.start()
    t2.start()

if __name__ == "__main__":
    main()
```
そうすれば

`coding0
2019-01-22 15:31:18.182620
drawing0
2019-01-22 15:31:18.182620
coding1
2019-01-22 15:31:19.183485
drawing1
2019-01-22 15:31:19.184489
coding2
2019-01-22 15:31:20.184271
drawing2
2019-01-22 15:31:20.185280`
このような結果が出てきてます
実行終わるまで`2.0026599999999988`秒使用しました
:point_up:一般処理を行う時と比較すると**時間が半分以下**になりました
本来一つ処理が終わるまで他の処理が待たされてる状態ですが
今並列で処理されることになりました

###すねかじりシミュレーション

簡単な実例を並列処理でやってみましょう

**想定ストーリー**
無職が両親のすねかじって生きてます、親が仕送りを止め,貯金が尽き,バイトし始めるの流れを並列処理でシミュレーションしてみましょう:rolling_eyes:ここは無職が一人息子と想定:man_tone3:親は共働きとします:couple:


- `貯金は親が貯めて無職が使うため,グローバル変数として宣言`
- `またデータの乱れが生じない為,グローバル変数の値を修正する際にロックをかけます`


```python:musyoku.py

"""先ず使用するモジュールを入れましょう"""
import threading
import random
import time

"""貯金を宣言,普通1000円はあり得ないけど,見やすくするためここは1000円とします"""
gMoney = 1000

"""ロックも作ります"""
gLock = threading.Lock

"""ここで二つの変数を宣言"""
anger = 0 #親が無職に対しての怒り
hunger = 0 #無職の腹減り

"""先ず親クラスを定義しましょう"""
class parent(threading.Thread):
    def run(self):
        global gMoney
        while True:
            money = random.randint(100,1000)
            """グローバル変数貯金の値を修正するので一旦ロックを掛けます"""
            gLock.acquire()
            """怒りが10まで貯まったら仕送りはやめる"""
            if gTimes >= 10:
                gLock.release()
                break
            gMoney +=money
            print('%sが%s円を稼ぎ仕送りしました,残り%s円' %(threading.current_thread(), money, gMoney))
            """一回の振込に付き,怒り点数が1プラス"""
            anger += 1
            """ロック解除"""
            gLock.release()
            time.sleep(0.5)

"""無職のクラスを定義"""
class unemployed(threading.Thread):
    def run(self):
        global gMoney
        while True:
              money = random.randint(100, 1000)
              gLock.acquire()
            """ここで一回確認入れます,貯金足りなければもちろん使えません"""
            if gMoney >= money:
               gMoney -= money
               print('%sが%s円を使いました,残り%s円です' %(threading.current_thread(), money, gMoney))
           """またロック解除はif文の外におかないと処理が止まってしまう可能性があります"""
            else:
                 if gTimees >= 5:
                    gLock.release()
                    print("無職がバイトし始めた")
                    break
       
                print('%sが%s円を使いたいけど,貯金が%s円しかありません' %(threading.current_thread(), money, gMoney))
               """お金使いたいけど残高不十分なため腹減り+1"""
                hunger += 1
           """ロック解除"""
            gLock.release()
            time.sleep(0.5)
              
def main():
"""一人の無職"""
    t_1 = unemployed(name='無職')
    t_1.start()

"""共働きの両親"""
    for x in range(2):
        t = parent(name='両親')
        t.start()

if __name__ == "__main__":
    main()

```

####実際プログラムを実行してみましょう

`
<unemployed(無職, started 8556)>が540円を使いました,残り460円です
<parent(両親, started 16548)>が128円を稼ぎ貯金しました,残り588円
<parent(両親, started 12824)>が696円を稼ぎ貯金しました,残り1284円
<parent(両親, started 12824)>が277円を稼ぎ貯金しました,残り1561円
<parent(両親, started 16548)>が290円を稼ぎ貯金しました,残り1851円
<unemployed(無職, started 8556)>が343円を使いました,残り1508円です
<parent(両親, started 16548)>が933円を稼ぎ貯金しました,残り2441円
<unemployed(無職, started 8556)>が241円を使いました,残り2200円です
<parent(両親, started 12824)>が320円を稼ぎ貯金しました,残り2520円
<parent(両親, started 12824)>が893円を稼ぎ貯金しました,残り3413円
<unemployed(無職, started 8556)>が794円を使いました,残り2619円です
<parent(両親, started 16548)>が924円を稼ぎ貯金しました,残り3543円
<unemployed(無職, started 8556)>が340円を使いました,残り3203円です
<parent(両親, started 16548)>が136円を稼ぎ貯金しました,残り3339円
<parent(両親, started 12824)>が650円を稼ぎ貯金しました,残り3989円
<unemployed(無職, started 8556)>が118円を使いました,残り3871円です
<unemployed(無職, started 8556)>が842円を使いました,残り3029円です
<unemployed(無職, started 8556)>が316円を使いました,残り2713円です
<unemployed(無職, started 8556)>が694円を使いました,残り2019円です
<unemployed(無職, started 8556)>が514円を使いました,残り1505円です
<unemployed(無職, started 8556)>が685円を使いました,残り820円です
<unemployed(無職, started 8556)>が182円を使いました,残り638円です
<unemployed(無職, started 8556)>が959円を使いたいけど,貯金が638円しかありません
<unemployed(無職, started 8556)>が664円を使いたいけど,貯金が638円しかありません
<unemployed(無職, started 8556)>が569円を使いました,残り69円です
<unemployed(無職, started 8556)>が481円を使いたいけど,貯金が69円しかありません
<unemployed(無職, started 8556)>が827円を使いたいけど,貯金が69円しかありません
<unemployed(無職, started 8556)>が226円を使いたいけど,貯金が69円しかありません
無職がバイトし始めた`

貯金尽きた無職がやっと社会復帰できましたね:relaxed:

#まとめ
並列処理に関する参考文献[公式ドキュメント]
(https://docs.python.jp/3/library/threading.html)
シミュレーションを書いて何故か自分の人生を考えてしまう:thinking:
エンジニアになるまで人生を迷走してしまう時期がありました,好きでもない職についてしまい、手に職もつかず,将来への不安が募るばかりでした,
    あるきっかけを得て未経験からエンジニアへ転職できて,今は充実してる毎日を過ごしてます:relaxed:

未経験がエンジニアへ転職する場合、最初は分からないことが多くて,苦い思いも多かったと思います,でも正しい勉強方法と時間を重ねて行けばきっと人前のエンジニアになれます,努力すればいつか実る時がくる,一緒に頑張りましょう:family: