一、进程与线程

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的更多相关文章

  1. python网络编程学习《一》

    最近,刚实习完,很喜欢实验楼,但是自己的方向仍然不能确定,自己觉得可选择的空间很大,尽管已经是大四的人了,想到别人都在忙着买职业装,买高跟鞋面试,学习化妆什么的,看看自己,反而开始慢慢关注运动,食疗以 ...

  2. python网络编程学习笔记(三):socket网络服务器(转载)

    1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象  建立socket对 ...

  3. Python网络编程学习_Day11

    一.协程 1.理论知识 协程,又称伪线程,是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈. ...

  4. Python网络编程学习_Day9

    一.socketserver实现多并发 socket只能实现单进程通讯,要实现多进程同时和服务端通讯就要使用socketserver. 代码如下: import socket client = soc ...

  5. python网络编程学习笔记(10):webpy框架

    转载请注明:@小五义http://www.cnblogs.com/xiaowuyi django和webpy都是python的web开发框架.Django的主要目的是简便.快速的开发数据库驱动的网站. ...

  6. Python网络编程基础|百度网盘免费下载|零基础入门学习资料

    百度网盘免费下载:Python网络编程基础|零基础学习资料 提取码:k7a1 目录: 第1部分 底层网络 第1章 客户/服务器网络介绍 第2章 网络客户端 第3章 网络服务器 第4章 域名系统 第5章 ...

  7. Python学习(22)python网络编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

  8. 《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档

    Foundations of Python Network Programing,Third Edition <python网络编程>,本书中的代码可在Github上搜索fopnp下载 本 ...

  9. Python 网络编程相关知识学习

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

随机推荐

  1. UML和绘图工具Visio介绍

    UML系列01之 UML和绘图工具Visio介绍 概要 UML,全称是Unified Modeling Language,中文是"统一建模语言".通俗点说,UML是一种创建模型的语 ...

  2. Binder机制,从Java到C (8. ServiceManager in Native)

    在第三篇 Binder机制,从Java到C (3. ServiceManager in Java) 中,讲到ServiceManager的Stub端在Native,Proxy端在Java.实际上,还要 ...

  3. 线程池python

    原创博文,转载请注明出处 今天在学习python进程与线程时,无意间发现了线程池threadpool模块,见官方文档. 模块使用非常简单,前提是得需要熟悉线程池的工作原理. 我们知道系统处理任务时,需 ...

  4. [转]Avoiding GDB Signal Noise.

    原文:http://peeterjoot.wordpress.com/2010/07/07/avoiding-gdb-signal-noise/ A quick note for future ref ...

  5. BEncoding的编码与解码

    BEncoding的编码与解码   1. BEncoding规则 BEncoding是BitTorrent用在传输数据结构的编码方式,我们最熟悉的“种子”文件,它里面的元数据就是 BEncoding ...

  6. UISearchDisplayController UISearchBar

    分组表+本地搜索 UISearchDisplayController  UISearchBar 的使用 效果图 @interface CityListViewController :UIViewCon ...

  7. c语言:将二进制数按位输出

    问题: 1.输入int 20,其二进制为10100,按位输出10100; 2.或者将1转化为“+”,0转化为“-”,输出就是” + - + - - “; int biTofh(int bi,int l ...

  8. ASP.NET MVC页面UI之多级数据选择UI(行业信息、专业信息、职位信息的选择)

    多级数据选择操作在开发中是常见的操作,比如选择行业信息时,一般有个大类,每个大类下边又包含很多小类,本文简单实现了弹出窗口一级一级选择功能. 本文博客出处:http://www.kwstu.com/A ...

  9. MyEclipse取消Show in Breadcrumb的方法

    eclipse中的Show in Breadcrumb是快速导航条,可以清晰的看到我们当前的类,属性或方法的导航 定位. 如果不喜欢的话,取消掉的方法如下: Window -> Customiz ...

  10. 初探原生js根据json数据动态创建table

    初探原生js根据json数据动态创建table 小生以实习生的职位进入了一家非纯软件的公司做asp.net开发,大半个月下来发现公司里居然没有前端工程师,这令我很诧异,跟着公司做项目,发现前端后台没有 ...