#!/usr/bin/env python # coding: utf-8 # # subprocess.Popen # In[1]: get_ipython().run_cell_magic('writefile', 'date1.py', "\nimport subprocess\n\nsubprocess.Popen('date')\n") # In[2]: get_ipython().system('python3.4 date1.py') # In[3]: get_ipython().run_cell_magic('writefile', 'date2.py', "\nimport subprocess\n\nsubprocess.Popen(['date', '+%H:%M:%S'])\n") # In[4]: get_ipython().system('python3.4 date2.py') # In[5]: get_ipython().run_cell_magic('writefile', 'date3.py', "\nimport subprocess\n\nsubprocess.Popen('date +%H:%M:%S', shell=True)\n") # In[6]: get_ipython().system('python3.4 date3.py') # In[7]: get_ipython().run_cell_magic('writefile', 'date4.py', "\nimport subprocess\n\nsubprocess.Popen('date', stdout=subprocess.DEVNULL)\n") # In[8]: get_ipython().system('python3.4 date4.py') # In[9]: import subprocess p = subprocess.Popen('cat', stdin=subprocess.PIPE, stdout=subprocess.PIPE) p.stdin.write(b'Hello!\n') p.stdin.close() print(p.poll()) print(p.stdout.read()) print(p.poll()) # # fork # In[1]: get_ipython().run_cell_magic('writefile', 'fork.py', "\nimport os\n\npid = os.fork()\nif pid:\n # parent\n for _ in range(200):\n print('hello from parent')\nelse:\n # child\n for _ in range(200):\n print('hello from child')\n") # In[2]: get_ipython().system('python3.4 fork.py') # # threading # ## def # In[1]: get_ipython().run_cell_magic('writefile', 'threads1.py', "\nimport threading\n\ndef action():\n for _ in range(10):\n print('hello from', threading.current_thread().name)\n\nfor _ in range(10):\n thread = threading.Thread(target=action)\n thread.start()\n") # In[2]: get_ipython().system('python3.4 threads1.py') # ## class # In[1]: get_ipython().run_cell_magic('writefile', 'threads2.py', "\nimport threading\n\nclass Worker(threading.Thread):\n def run(self):\n for _ in range(10):\n print('hello from', threading.current_thread().name)\n\nfor _ in range(10):\n thread = Worker()\n thread.start()\n") # In[2]: get_ipython().system('python3.4 threads2.py') # ## Неатомарный инкремент в препарированном виде # In[1]: import threading import time counter = 0 def inc(): global counter v = counter time.sleep(0.001) counter = v + 1 pool = [] for _ in range(1000): th = threading.Thread(target=inc) th.start() pool.append(th) for th in pool: th.join() print(counter) # ## Неатомарный инкремент # In[1]: import threading counter = 0 def inc(): global counter for _ in range(100000): counter += 1 pool = [] for _ in range(10): th = threading.Thread(target=inc) th.start() pool.append(th) for th in pool: th.join() print(counter) # ## Синхронизация потоков при помощи блокировки # In[1]: import threading import time counter = 0 lock = threading.Lock() def inc(): global counter lock.acquire() v = counter time.sleep(0.001) counter = v + 1 lock.release() pool = [] for _ in range(1000): th = threading.Thread(target=inc) th.start() pool.append(th) for th in pool: th.join() print(counter) # ## Использование with вместе с lock # In[1]: import threading import time counter = 0 lock = threading.Lock() def inc(): global counter with lock: v = counter time.sleep(0.001) counter = v + 1 pool = [] for _ in range(1000): th = threading.Thread(target=inc) th.start() pool.append(th) for th in pool: th.join() print(counter) # ## Взаимные блокировки, deadlock # In[3]: import threading import time lock1 = threading.Lock() lock2 = threading.Lock() def good(): with lock1: time.sleep(0.001) if lock2.acquire(timeout=1): print('good') lock2.release() else: print('locking failed :(') def bad(): with lock2: if lock1.acquire(timeout=1): print('bad') lock1.release() else: print('locking failed :(') threading.Thread(target=good).start() threading.Thread(target=bad).start()