Pythonで並列処理 大学生の課題を例に

まず、Pythonにおいてタイムアウトを実装したく、並列処理に調べました。その結果以下の情報が必要だと分かりました

①、時間のかかる処理プログラム
②、①を実行して何秒経過したか判定
③、①の処理が時間内に終了したか判定

ここでは中間報告を控えた大学生としてプログラムを作成しました


```python:work.py
import time
import threading
import queue
import random

boo=0
sintyoku=0

def kakunin(n,s):
  global boo
  for a in range(1,n+1):
   time.sleep(0.9)
   print(a,"日目ーーーー")
  boo=1
  print("中間報告日到来")
  #return
  for a in range(n+1,s+1):
   time.sleep(0.9)
   print(a,"日目ーーーー")
  if s+1==s-1:
      print("一夜漬けしかないぞ")
  else:
      print("早めにやってよかった")
  #return

def homework(n,q):
  global sintyoku
  for a in range(1,n+1):
   time.sleep(1)
  sintyoku=1
  print("中間報告完了っと")
  q.put("報告書")
  return

def simekiri(n):
   global sintyoku
   check=0
   while True:
    if boo==1:
       if sintyoku==0:
          print("中間報告日だぞまだか！！",boo)
          return
       elif sintyoku==1:
          print("中間報告日間に合ったえらい",sintyoku)
          return
    elif boo==0 and check==0:
       if sintyoku==0:
          print("スタート")
          check=1
       elif sintyoku==1:
           pass
          #print("スタート前に終わることはないのでコメントアウト")

def main():
  global boo
  global sintyoku
  simekirisec=random.randrange(8, 10, 1)
  kakuninsec=random.randrange(3, 5, 1)
  homeworksec=random.randrange(2, simekirisec, 1)
  print("締切日:",simekirisec,"日後")
  print("中間報告日:",kakuninsec,"日後")
  print("報告予定:",homeworksec,"日後")
  q = queue.Queue()
  thread1 = threading.Thread(target=simekiri, args=(simekirisec,))
  thread2 = threading.Thread(target=kakunin, args=(kakuninsec,simekirisec))
  thread3 = threading.Thread(target=homework, args=(homeworksec,q))
  thread1.start()
  thread2.start()
  thread3.start()
  thread1.join()
  thread2.join(simekirisec)
  thread3.join(simekirisec)
  rslt = q.get_nowait()
  print("内容：",rslt)
  boo=0
  sintyoku=0
for t in range(1):
  print(t,"回目施行")
  main()

print("ok")
```

実行すると以下のようになります!

![bandicam 2022-01-25 08-43-06-713.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522233/c172c6c9-8acb-7d28-2d7b-183b671a82c5.jpeg)


時間のかかる処理をレポートの中間報告予定日として、確認日を中間報告日として、締め切りは処理を待つ最大時間です。
simekiriで、while文で報告日、報告日時点での進捗を常に監視
homeworkで、時間のかかる処理、
kakuninで、中間報告日までのカウントダウンをしています。


しっかり(?)タイムアウトを実装すると以下のようになります。

```python:work
import time
import threading
import queue
import random

boo=0
sintyoku=0

def kakunin(n):
  global boo
  time.sleep(n)
  boo=1
  print(n,"秒経過。確認")

def homework(q,a):
  global sintyoku
  time.sleep(2)
  q.put("res")
  sintyoku=1
  return

def simekiri(q):
   global sintyoku
   while True:
    if boo==1:
       if sintyoku==0:
          print("まだ終わっていない")
          return "まだ終わっていない"
       else:
          print("終わった")
          return "終わった"
def main(a):
  global boo
  global sintyoku
  kakuninsec=1
  q = queue.Queue()
  thread1 = threading.Thread(target=simekiri, args=(q,))
  thread2 = threading.Thread(target=kakunin, args=(kakuninsec,))
  thread3 = threading.Thread(target=homework, args=(q,a,))
  thread1.start()
  thread2.start()
  thread3.start()
  thread2.join(kakuninsec)
  thread3.join(kakuninsec)
  thread1.join(kakuninsec)
  rslt = q.get()
  print("内容：",rslt,type(rslt))
  boo=0
  sintyoku=0
  return
for t in range(1):
  print(t,"回目施行")
  main(a)

print("ok")
```

homework内のsleepをkakuninsecの1より大きくするか小さくするかで結果が変わります。
自分のために書いたもののため分かりにくいと思いますが、読んでいただきありがとうございます。