Geventの良さ4

昨日の続きします。

multiprocessingのPoolとProcessの違いがちょっとわからなかったんですが、聞いてみたところ、Processは人で,Poolは部屋だそうです。なるほど。わかりやすすぎる。

> http://ideone.com/GhpaJU
> これの、
> gevent.sleep(0)って必要ですか?


これはコンテキストスイッチさせているんですが、イメージわかりますかね?
OSのプロセススケジューリングと同じです。

1.geventはマルチプロセスではないのでプロセスは1つ、CPU(コア)を一つだけ使える
2. 一つのCPUを複数のgreenletで順番に切り替えながら使う
(あるときに動いているgreenletは1つだけ)
3.動いているgreenletがgevent.sleep(0)とすると、CPUを次の人に渡す(コンテキストスイッチ)これはコンテキストスイッチさせているんですが、イメージわかりますかね?
OSのプロセススケジューリングと同じです。
なかなかいい絵がないんですが、↓こういう感じです。
4. geventはマルチプロセスではないのでプロセスは1つ、CPU(コア)を一つだけ使える
5.一つのCPUを複数のgreenletで順番に切り替えながら使う
(あるときに動いているgreenletは1つだけ)
動いているgreenletがgevent.sleep(0)とすると、CPUを次の人に渡す(コンテキストスイッチ

ってなんでこんなわかりやすく説明できるんでしょ…

f:id:reonreon3reon:20140329184632j:plain

#source 01.py
from multiprocessing import Process, Queue
 
def f(queue):
    queue.put([42, None, 'hello'])
 
if __name__ == '__main__':
    queue = Queue()
    p = Process(target=f, args=(queue,))
    p.start()
    print(queue.get())   # prints "[42, None, 'hello']"
    p.join()
#source 02.py
# your code goes here
from multiprocessing import Process, Pipe
 
def f(conn):
    conn.send([42, None, 'hello'])
    conn.close()
 
if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print(parent_conn.recv())   # prints "[42, None, 'hello']"
    p.join()

source 01.pyと02.pyは全く同じ挙動をしているということです。
もうちょっと勉強する必要があります…。


あと、こんな宿題も出してもらいました。

#source 03.py
from multiprocessing import Process
import time
 
def f(queue):
    queue.insert(0, [42, None, 'hello'])   # queue.push()
 
if __name__ == '__main__':
    queue = []   # using list as queue
    p = Process(target=f, args=(queue,))
    p.start()
 
    # get value from the child
    while True:
        try:
            val = queue.pop()
            break
        except IndexError:  # queue is empty
            time.sleep(0.1)
 
    print(val)   # never reached!
    p.join()
#source 04.py
from threading import Thread
import time
 
def f(queue):
    queue.insert(0, [42, None, 'hello'])   # queue.push()
 
if __name__ == '__main__':
    queue = []   # using list as queue
    p = Thread(target=f, args=(queue,))
    p.start()
 
    # get value from the child
    while True:
        try:
            val = queue.pop()
            break
        except IndexError:  # queue is empty
            time.sleep(0.1)
 
    print(val)   # works fine
    p.join()

内容

source03.pyと04.pyは一見同じように見えますが、
multiprocessingだとlistをQueueのように使えず、
threadingだと使えるというとのことです。

それはなぜかという宿題です。

ヒント

メモリ空間


だそうです。本当にありがたいです。
頑張って僕なりの答えを出したいと思います。