python学习日志--day10

来源:互联网 发布:mac os x 升级系统 编辑:程序博客网 时间:2024/06/03 19:49

一、笔记

1、IO操作不占用cpu

2、计算占用cpu

3、python多线程,不适合cpu密集操作型的任务,适合IO操作密集型的任务


二、多进程(multiprocessing)

from multiprocessing import Processimport os# 子进程要执行的代码def run_proc(name):    print ('Run child process %s (%s)...' % (name, os.getpid()))if __name__=='__main__':    print ('Parent process %s.' % os.getpid())    p = Process(target=run_proc, args=('test',))    print ('Process will start.')    p.start()    p.join()    print ('Process end.')

输出结果



from multiprocessing import Processimport osdef info(title):    print(title)    print('module name:', __name__)    print('parent process:', os.getppid())    print('process id:', os.getpid())    print("\n\n")def f(name):    info('\033[31;1mcalled from child process function f\033[0m')    print('hello', name)if __name__ == '__main__':    info('\033[32;1mmain process line\033[0m')    p = Process(target=f, args=('bob',))    p.start()

输出结果



进程间通信(不同进程间内存是不共享的

from multiprocessing import Process, Queuedef f(q):    q.put([42, None, 'hello'])if __name__ == '__main__':    q = Queue()    p = Process(target=f, args=(q,))    p.start()    print(q.get())    # prints "[42, None, 'hello']"    p.join()

输出结果



进程池

  • apply
  • apply_async
from  multiprocessing import Process, Pool,freeze_supportimport timeimport osdef Foo(i):    time.sleep(2)    print("in process",os.getpid())    return i + 100def Bar(arg):    print('-->exec done:', arg,os.getpid())if __name__ == '__main__':    #freeze_support()    pool = Pool(processes=3) #允许进程池同时放入5个进程    print("主进程",os.getpid())    for i in range(10):        pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调        #pool.apply(func=Foo, args=(i,)) #串行        #pool.apply_async(func=Foo, args=(i,)) #串行    print('end')    pool.close()    pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()

输出结果



协程(Coroutine)--一种用户态的轻量级线程

定义:

  • 必须在只有一个单线程里实现并发
  • 修改共享数据不需加锁
  • 用户程序里自己保存多个控制流的上下文栈
  • 一个协程遇到IO 操作自动切换到其他协程


优点:

  • 无需线程上下文切换的开销
  • 无需原子操作锁定及同步的开销(原子操作:不会被线程调度机制打断的操作)
  • 方便切换控制流,简化编程模型
  • 高并发+高扩展+低成本
Greenlet

from greenlet import greenletdef test1():    print(12)    gr2.switch()    print(34)    gr2.switch()def test2():    print(56)    gr1.switch()    print(78)gr1 = greenlet(test1) #启动一个携程gr2 = greenlet(test2)gr1.switch()

输出结果




Gevent

import geventdef foo():    print('Running in foo')   #切换bar-print    gevent.sleep(2)   #切换    print('Explicit context switch to foo again')def bar():    print('Explicit精确的 context内容 to bar')   #切换到func3-print
    gevent.sleep(1)
print('Implicit context switch back to bar')def func3(): print("running func3 ") #切换到foo-gevent,卡住;切换到bar-gevent,卡住,直接执行func3-geven,没卡住,func3-print2 gevent.sleep(0) print("running func3 again ")gevent.joinall([ gevent.spawn(foo), #生成, gevent.spawn(bar), gevent.spawn(func3),])

输出结果



简单的网页爬虫


from urllib import requestdef f(url):    print('GET: %s' % url)    resp = request.urlopen(url)    data = resp.read()    f = open("url.html","wb")    f.write(data)    f.close()    print('%d bytes received from %s.' % (len(data), url))f("http://www.cnblogs.com/alex3714/articles/5248247.html")

输出结果



生成的文件



IO多路复用

  • 虚拟空间分为:用户空间和内核空间

select解析socket通信

服务器端import selectimport socketimport queueserver = socket.socket()server.bind(('localhost',9000))server.listen(1000)server.setblocking(False) #不阻塞msg_dic = {}inputs = [server,]#inputs = [server,conn] #[conn,]#inputs = [server,conn,conn2] #[conn2,]outputs = [] ##outputs = [r1,] #while True:    readable ,writeable,exceptional= select.select(inputs, outputs, inputs )    print(readable,writeable,exceptional)    for r in readable:        if r is server: #代表来了一个新连接            conn,addr = server.accept()            print("来了个新连接",addr)            inputs.append(conn) #是因为这个新建立的连接还没发数据过来,现在就接收的话程序就报错了,            #所以要想实现这个客户端发数据来时server端能知道,就需要让select再监测这个conn            msg_dic[conn] = queue.Queue() #初始化一个队列,后面存要返回给这个客户端的数据        else: #conn2            data = r.recv(1024)            print("收到数据",data)            msg_dic[r].put(data)            outputs.append(r) #放入返回的连接队列里            # r.send(data)            # print("send done....")    for w in writeable: #要返回给客户端的连接列表        data_to_client = msg_dic[w].get()        w.send(data_to_client) #返回给客户端源数据        outputs.remove(w) #确保下次循环的时候writeable,不返回这个已经处理完的连接了    for e in exceptional:        if e in outputs:            outputs.remove(e)        inputs.remove(e)        del msg_dic[e]

客户端import socketHOST = 'localhost'  # The remote hostPORT = 9001  # The same port as used by the servers = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((HOST, PORT))while True:    msg = bytes(input(">>:"), encoding="utf8")    s.sendall(msg)    data = s.recv(1024)    #    print('Received', data)s.close()





原创粉丝点击