Python网络编程学习_Day10
一、进程与线程
1.区别
进程:一个程序要运行时所需要的所有资源的集合,进程是资源的集合。
一个进程至少需要一个线程,这个线程称为主线程
一个进程里面可以有多个线程
两个进程之间的数据是完全独立,不能互相访问。
线程:一道单一的指令控制流,寄生在进程中。
单一进程里多个进程是共享数据的,多个线程在涉及修改同一个数据时,要加锁。
2.线程调用方法
import threading
import time def sayhi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__': t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例 t1.start() #启动线程
t2.start() #启动另一个线程 print(t1.getName()) #获取线程名
print(t2.getName())
import threading
import time def sayhi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__': t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例 t1.start() #启动线程
t2.start() #启动另一个线程 print(t1.getName()) #获取线程名
print(t2.getName())
3.守护线程
守护线程一旦退出,其子线程都会退出。
代码举例如下:
import time
import threading def run(n): print('[%s]------running----\n' % n)
time.sleep(2)
print('--done--') def main():
for i in range(5):
t = threading.Thread(target=run,args=[i,])
t.start()
t.join(1)
print('starting thread', t.getName()) m = threading.Thread(target=main,args=[])
m.setDaemon(True) #将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务
m.start()
m.join(timeout=2)
print("---main thread done----")
4.线程锁
多个线程修改同一个数据时要加锁。
import time
import threading def addNum():
global num #在每个线程中都获取这个全局变量
print('--get num:',num )
time.sleep(1)
lock.acquire() #修改数据前加锁
num -=1 #对此公共变量进行-1操作
lock.release() #修改后释放 num = 100 #设定一个共享变量
thread_list = []
lock = threading.Lock() #生成全局锁
for i in range(100):
t = threading.Thread(target=addNum)
t.start()
thread_list.append(t) for t in thread_list: #等待所有线程执行完毕
t.join() print('final num:', num )
5.semaphore(信号量)
import threading,time def run(n):
semaphore.acquire()
time.sleep(1)
print("run the thread: %s\n" %n)
semaphore.release() if __name__ == '__main__': num= 0
semaphore = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
for i in range(20):
t = threading.Thread(target=run,args=(i,))
t.start() while threading.active_count() != 1:
pass #print threading.active_count()
else:
print('----all threads done---')
print(num)
6.Event
event有三个指令,event.set(),event.wait(),event.clear(),通过event实现多个线程间的交互。
交通指挥灯实例:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Liumj
import threading
import time
def lighter():
count = 0
while True:
if count<30:
if not event.is_set():
event.set()
print("\033[32;1m绿灯--\033[0m")
elif count <34:
print("\033[33;1m黄灯--\033[0m")
elif count<60:
if event.is_set():
event.clear()
print("\033[31;1m红灯--\033[0m")
else:
count = 0
count +=1
time.sleep(0.5)
def car(n):
count = 0
while True:
event.wait()
print("car [%s] is running..." % n)
count +=1
time.sleep(1)
event = threading.Event()
red_light = threading.Thread(target=lighter)
red_light.start()
c1 = threading.Thread(target=car,args=(2,))
c1.start()
二、queue队列
三种类型:
- class
queue.
Queue
(maxsize=0) #先入先出
- class
queue.
LifoQueue
(maxsize=0) #last in fisrt out - class
queue.
PriorityQueue
(maxsize=0) #存储数据时可设置优先级的队列
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Liumj
import queue
#q = queue.Queue(maxsize = 2) #先进先出
#q = queue.LifoQueue() #后进先出
q = queue.PriorityQueue(maxsize=3) #后进先出
#q.put(1)
#q.put(2)
#q.put(3)
q.put([1,"alex"])
q.put([5,"eric"])
q.put([3,"liumj"])
print(q.empty())
print(q.full())
print(q.get())
print(q.get())
print(q.get())
三、生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Liumj
import threading
import queue
import time
def consumer(name):
while True:
print("%s 取到骨头[%s]吃了" %(name,q.get()))
time.sleep(0.5)
def producer(name):
count = 0
while q.qsize() <5:
print("%s 生产了骨头" %name,count)
q.put(count)
count+=1
time.sleep(3)
q = queue.Queue(maxsize=4)
p = threading.Thread(target=producer,args=("alex",))
p2 = threading.Thread(target=producer,args=("eric",))
c = threading.Thread(target=consumer,args=("李闯",))
p.start()
p2.start()
c.start()
四、多进程
multiprocessing是一个包,它支持使用类似于线程模块的API来生成进程。 多进程包提供本地和远程并发,通过使用子进程而不是线程有效地旁路全局解释器锁。 因此,多处理模块允许编程人员充分利用给定机器上的多个处理器。 它在Unix和Windows上运行
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Liumj
from multiprocessing import Process,Manager
def f(d,l,n):
d[n] = n
l.append(n)
#print(l)
if __name__ =="__main__":
with Manager() as manager:
d = manager.dict()
l = manager.list(range(5))
p_list=[]
for i in range(10):
p = Process(target=f,args=(d,l,i))
p.start()
p_list.append(p)
for res in p_list:
res.join()
print(d)
print(l)
五、进程间通信
不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:
from multiprocessing import Process, Queue def 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()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Liumj
from multiprocessing import Process,Pipe
def f(conn):
conn.send([42,None,'hello'])
conn.send([41,None,'hello'])
print("from parent",conn.recv())
print("from 2",conn.recv())
if __name__ == '__main__':
parent_conn,child_conn = Pipe()
p = Process(target=f,args=(child_conn,))
p.start()
print(parent_conn.recv())
parent_conn.send('hello son')
p.join()
manager多进程
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Liumj
from multiprocessing import Process,Manager
def f(d,l,n):
d[n] = n
l.append(n)
#print(l)
if __name__ =="__main__":
with Manager() as manager:
d = manager.dict()
l = manager.list(range(5))
p_list=[]
for i in range(10):
p = Process(target=f,args=(d,l,i))
p.start()
p_list.append(p)
for res in p_list:
res.join()
print(d)
print(l) 输入结果:
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
[0, 1, 2, 3, 4, 3, 2, 1, 0, 6, 4, 8, 5, 7, 9]
六、进程池
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
from multiprocessing import Process,Pool
import time def Foo(i):
time.sleep(2)
return i+100 def Bar(arg):
print('-->exec done:',arg) pool = Pool(5) for i in range(10):
pool.apply_async(func=Foo, args=(i,),callback=Bar)
#pool.apply(func=Foo, args=(i,)) print('end')
pool.close()
pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
Python网络编程学习_Day10的更多相关文章
- python网络编程学习《一》
最近,刚实习完,很喜欢实验楼,但是自己的方向仍然不能确定,自己觉得可选择的空间很大,尽管已经是大四的人了,想到别人都在忙着买职业装,买高跟鞋面试,学习化妆什么的,看看自己,反而开始慢慢关注运动,食疗以 ...
- python网络编程学习笔记(三):socket网络服务器(转载)
1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象 建立socket对 ...
- Python网络编程学习_Day11
一.协程 1.理论知识 协程,又称伪线程,是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈. ...
- Python网络编程学习_Day9
一.socketserver实现多并发 socket只能实现单进程通讯,要实现多进程同时和服务端通讯就要使用socketserver. 代码如下: import socket client = soc ...
- python网络编程学习笔记(10):webpy框架
转载请注明:@小五义http://www.cnblogs.com/xiaowuyi django和webpy都是python的web开发框架.Django的主要目的是简便.快速的开发数据库驱动的网站. ...
- Python网络编程基础|百度网盘免费下载|零基础入门学习资料
百度网盘免费下载:Python网络编程基础|零基础学习资料 提取码:k7a1 目录: 第1部分 底层网络 第1章 客户/服务器网络介绍 第2章 网络客户端 第3章 网络服务器 第4章 域名系统 第5章 ...
- Python学习(22)python网络编程
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
- 《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档
Foundations of Python Network Programing,Third Edition <python网络编程>,本书中的代码可在Github上搜索fopnp下载 本 ...
- Python 网络编程相关知识学习
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
随机推荐
- 在GridView的中有一个DropDownList,并且DropDownList有回传事件
在GridView的中有一个DropDownList,并且DropDownList有回传事件 最近做一个项目,需要在GridView中的ItemTemplate中添加一个DropDownList,并且 ...
- c# UDP/TCP协议简单实现(简单聊天工具)
长时间没有摸这两个协议,写个代码温习下 下面是界面 [服务器界面] [登陆界面] [好友列表界面(我登陆了2个)] [聊天界面] 下面大致讲解下用到的内容 1.用户登陆于服务器通信用到的tcp协议,服 ...
- seajs代码
打包并压缩seajs代码 背景 seajs是一款优秀的模块开发插件,但是当我们使用它来进行模块化开发的时候,由于它的每个模块的加载都会进行一次http请求,那么当模块数量倍增的时候,会拖慢页面的加载速 ...
- highlight高亮
玩转正则之highlight高亮 2013-10-07 05:16 by 靖鸣君, 584 阅读, 3 评论, 收藏, 编辑 程序员在编写代码的时候少不了和字符串以及“查询”打交道,两者的交集中有一个 ...
- Clob类型转换成String类型
oracle中表结构如下: create table GRID_RESOURCE ( ID VARCHAR2(50), CNNAME VARCHAR2(50), TYPE VARCHAR2(50), ...
- 使用entity framework开发oracle
A.vs2010 SP1 B.ODAC(http://www.oracle.com/technetwork/database/windows/downloads/index-101290.html) ...
- ArcEngine关于单位转换示例
示例界面: 转换代码: private void Button1_Click(object sender, System.Windows.RoutedEventArgs e) { // Get the ...
- ASP.NET MVC:多语言的三种技术处理策略
ASP.NET MVC:多语言的三种技术处理策略 背景 本文介绍了多语言的三种技术处理策略,每种策略对应一种场景,这三种场景是: 多语言资源信息只被.NET使用. 多语言资源信息只被Javascrip ...
- Windbg是windows平台上强大的调试器
基础调试命令 - .dump/.dumpcap/.writemem/!runaway Windbg是windows平台上强大的调试器,它相对于其他常见的IDE集成的调试器有几个重要的优势, Windb ...
- 飘逸的python - zlib压缩存到数据库
当每天有大量的数据存到kv数据库中去,且value数据很大,于是想压缩后再存进去. 之前提到了 gzip压缩,为什么不直接用gzip呢. 其实更确切的说gzip是一种文件格式,它压缩成gzip文件,而 ...