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())

  

 1 import threading
 2 import time
 3
 4 def sayhi(num): #定义每个线程要运行的函数
 5
 6     print("running on number:%s" %num)
 7
 8     time.sleep(3)
 9
10 if __name__ == ‘__main__‘:
11
12     t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
13     t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例
14
15     t1.start() #启动线程
16     t2.start() #启动另一个线程
17
18     print(t1.getName()) #获取线程名
19     print(t2.getName())

3.守护线程

守护线程一旦退出,其子线程都会退出。

代码举例如下:

 1 import time
 2 import threading
 3
 4
 5 def run(n):
 6
 7     print(‘[%s]------running----\n‘ % n)
 8     time.sleep(2)
 9     print(‘--done--‘)
10
11 def main():
12     for i in range(5):
13         t = threading.Thread(target=run,args=[i,])
14         t.start()
15         t.join(1)
16         print(‘starting thread‘, t.getName())
17
18
19 m = threading.Thread(target=main,args=[])
20 m.setDaemon(True) #将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务
21 m.start()
22 m.join(timeout=2)
23 print("---main thread done----")

4.线程锁

多个线程修改同一个数据时要加锁。

 1 import time
 2 import threading
 3
 4 def addNum():
 5     global num #在每个线程中都获取这个全局变量
 6     print(‘--get num:‘,num )
 7     time.sleep(1)
 8     lock.acquire() #修改数据前加锁
 9     num  -=1 #对此公共变量进行-1操作
10     lock.release() #修改后释放
11
12 num = 100  #设定一个共享变量
13 thread_list = []
14 lock = threading.Lock() #生成全局锁
15 for i in range(100):
16     t = threading.Thread(target=addNum)
17     t.start()
18     thread_list.append(t)
19
20 for t in thread_list: #等待所有线程执行完毕
21     t.join()
22
23 print(‘final num:‘, num )

5.semaphore(信号量)

 1 import threading,time
 2
 3 def run(n):
 4     semaphore.acquire()
 5     time.sleep(1)
 6     print("run the thread: %s\n" %n)
 7     semaphore.release()
 8
 9 if __name__ == ‘__main__‘:
10
11     num= 0
12     semaphore  = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
13     for i in range(20):
14         t = threading.Thread(target=run,args=(i,))
15         t.start()
16
17 while threading.active_count() != 1:
18     pass #print threading.active_count()
19 else:
20     print(‘----all threads done---‘)
21     print(num)

6.Event

event有三个指令,event.set(),event.wait(),event.clear(),通过event实现多个线程间的交互。

交通指挥灯实例:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Liumj
 4 import threading
 5 import time
 6 def lighter():
 7     count = 0
 8     while True:
 9         if count<30:
10             if not event.is_set():
11                 event.set()
12             print("\033[32;1m绿灯--\033[0m")
13         elif count <34:
14             print("\033[33;1m黄灯--\033[0m")
15         elif count<60:
16             if event.is_set():
17                 event.clear()
18             print("\033[31;1m红灯--\033[0m")
19         else:
20             count = 0
21         count +=1
22         time.sleep(0.5)
23 def car(n):
24     count = 0
25     while True:
26         event.wait()
27         print("car [%s] is running..." % n)
28         count +=1
29         time.sleep(1)
30 event = threading.Event()
31 red_light = threading.Thread(target=lighter)
32 red_light.start()
33 c1 = threading.Thread(target=car,args=(2,))
34 c1.start()

二、queue队列

三种类型:

class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #last in fisrt out 
class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Liumj
 4 import queue
 5 #q = queue.Queue(maxsize = 2) #先进先出
 6 #q = queue.LifoQueue() #后进先出
 7 q = queue.PriorityQueue(maxsize=3) #后进先出
 8 #q.put(1)
 9 #q.put(2)
10 #q.put(3)
11 q.put([1,"alex"])
12 q.put([5,"eric"])
13 q.put([3,"liumj"])
14 print(q.empty())
15 print(q.full())
16 print(q.get())
17 print(q.get())
18 print(q.get())

三、生产者消费者模型

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Liumj
 4 import threading
 5 import queue
 6 import time
 7 def consumer(name):
 8     while True:
 9         print("%s 取到骨头[%s]吃了" %(name,q.get()))
10         time.sleep(0.5)
11 def producer(name):
12     count = 0
13     while q.qsize() <5:
14         print("%s 生产了骨头" %name,count)
15         q.put(count)
16         count+=1
17         time.sleep(3)
18 q = queue.Queue(maxsize=4)
19 p = threading.Thread(target=producer,args=("alex",))
20 p2 = threading.Thread(target=producer,args=("eric",))
21 c = threading.Thread(target=consumer,args=("李闯",))
22 p.start()
23 p2.start()
24 c.start()

四、多进程

multiprocessing是一个包,它支持使用类似于线程模块的API来生成进程。 多进程包提供本地和远程并发,通过使用子进程而不是线程有效地旁路全局解释器锁。 因此,多处理模块允许编程人员充分利用给定机器上的多个处理器。 它在Unix和Windows上运行

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Liumj
 4 from multiprocessing import Process,Manager
 5 def f(d,l,n):
 6     d[n] = n
 7     l.append(n)
 8     #print(l)
 9 if __name__ =="__main__":
10     with Manager() as manager:
11         d = manager.dict()
12         l = manager.list(range(5))
13         p_list=[]
14         for i in range(10):
15             p = Process(target=f,args=(d,l,i))
16             p.start()
17             p_list.append(p)
18         for res in p_list:
19             res.join()
20         print(d)
21         print(l)

五、进程间通信

不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:

 1 from multiprocessing import Process, Queue
 2
 3 def f(q):
 4     q.put([42, None, ‘hello‘])
 5
 6 if __name__ == ‘__main__‘:
 7     q = Queue()
 8     p = Process(target=f, args=(q,))
 9     p.start()
10     print(q.get())    # prints "[42, None, ‘hello‘]"
11     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多进程

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author:Liumj
 4 from multiprocessing import Process,Manager
 5 def f(d,l,n):
 6     d[n] = n
 7     l.append(n)
 8     #print(l)
 9 if __name__ =="__main__":
10     with Manager() as manager:
11         d = manager.dict()
12         l = manager.list(range(5))
13         p_list=[]
14         for i in range(10):
15             p = Process(target=f,args=(d,l,i))
16             p.start()
17             p_list.append(p)
18         for res in p_list:
19             res.join()
20         print(d)
21         print(l)
22
23 输入结果:
24 {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
25 [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()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
时间: 2024-10-09 21:19:08

Python网络编程学习_Day10的相关文章

python网络编程学习《一》

最近,刚实习完,很喜欢实验楼,但是自己的方向仍然不能确定,自己觉得可选择的空间很大,尽管已经是大四的人了,想到别人都在忙着买职业装,买高跟鞋面试,学习化妆什么的,看看自己,反而开始慢慢关注运动,食疗以及护肤了,哈哈,程序员就是酱紫,身体是革命的本钱.现在的方向至少是确定了,数据分析,但是图像处理这个项目既然当初选择当负责人,现在也要负责啊:那么目前学习网络编程,也是因为学长希望在“wind”的登陆上面实现c/s架构,那么我就试试吧,说不定,自己在量化投资或者网络上面也是可以的捏.废话不说,进入学

Python网络编程学习_day11

一.协程 1.理论知识 协程,又称伪线程,是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置. 优点: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销 "原子操作(atomic operation)是不需要synchronize

python网络编程学习2016/11/18

1.打印本机设备名以及IPv4地址 #!/usr/bin/python2.7 # -*- coding=utf-8 -*- import socket def print_machine_info(): host_name = socket.gethostname()                       #本机设备名 ip_address = socket.gethostbyname(host_name)   #设备名对应的ip 地址 print "%s \'s ip is %s&quo

python 网络编程:socket

在学习socket之前,我们先复习下相关的网络知识. OSI七层模型:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层.OSI七层模型是由国际标准化组织ISO定义的网络的基本结构,不仅包括一些概念和结构,还包括一系列的协议. TCP/IP四层模型:既然有OSI七层模型,为什么我们还要定义一个TCP/IP的四层模型呢,那是因为OSI七层模型对应面过于宽泛,很多概念实现不了,也没必要实现,因此,实际生产中广泛应用的是TCP/IP四层结构,他们的对应关系如下表: TCP/IP OSI 应用层

python网络编程,通过服务名称和会话类型(tcp,udp)获取端口号,简单的异常处理

作为一个php程序员,同时有对网络方面感兴趣,php就比较蛋疼了,所以就抽了些时间看python 之前学python基础因为工作原因,断断续续的看了个基础,差不多是可以写代码了 最近在看<python网络编程基础>,准备是边实践边学习了,对书上的一个例子做了个复制 cli下运行的代码 1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # ^设置编码:代码中有中午会导致编译错误 4 5 # 引入socket,sys模块 6 import so

Python网络编程02/基于TCP协议的socket简单的通信

目录 Python网络编程02/基于TCP协议的socket简单的通信 1.昨日内容回顾 2.socket 2.1 socket套接字 2.2 基于TCP协议的socket简单通信 Python网络编程02/基于TCP协议的socket简单的通信 1.昨日内容回顾 1.单播:单独联系某一个人 2.广播:给所有人发送消息(群发) 3.比特流:bit就是0101跟水流一样的源源不断的发送01010101 4.以太网协议:将数据进行分组:一组称之为一帧,数据报 head|data head:18字节:

网络编程学习小结

几种网络编程方式: ISAPI.CGI.WinInet.Winsock 它们之间的差别: 1)  ISAPI主要是开发基于浏览器client与server端程序.效率比CGI方式高,并且也扩展了CGI没有的一些功能.(基于TCP/IP模型中的应用层) 2)  CGI主要是开发基于浏览器client与server端程序.(基于TCP/IP模型中的应用层) 3)  WinInet主要是开发client程序.(基于TCP/IP模型中的应用层) 4)  Winsock主要是基于socket来开发clie

python 网络编程 (二)---tcp

异常 python的socket模块实际上定义了4种可能出现的异常: 1)与一般I/O 和通信问题有关的socket.error; 2)与查询地址信息有关的socket.gaierror; 3)与其他地址错误有关的socket.herror; 4)与在一个socket上调用settimeout()后,处理超时有关的socket.timeout; import socket, sys, time host = sys.argv[1] textport = sys.argv[2] filename

[Python网络编程] DNS缓存解决方案

记得以前写爬虫的时候为了防止dns多次查询,是直接修改/etc/hosts文件的,最近看到一个优美的解决方案,修改后记录如下: import socket _dnscache={} def _setDNSCache(): """ Makes a cached version of socket._getaddrinfo to avoid subsequent DNS requests. """ def _getaddrinfo(*args, **