pythonNet08

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。pythonNet08,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

线程通信

通信方法:多个线程共用进程空间,所以进程的全局变量对进程内线程均可见。线程往往使用全局变量进行通信

注意事项:线程间使用全局变量进行通信,全局变量为共享资源,往往需要同步互斥机制

线程的同步互斥

线程Event

e = threading.Event()  创建事件对象

e.wait([timeout])  事件阻塞函数

e.set()  设置事件
e.clear()  清除事件

pythonNet08
pythonNet08

 1 from threading import Thread 
 2 from time import sleep 
 3 
 4 a = 1
 5 
 6 def foo():
 7     global a
 8     a = 1000
 9 
10 def bar():
11     sleep(1)
12     print("a = ",a)
13 
14 t1 = Thread(target = foo)
15 t2 = Thread(target = bar)
16 
17 t1.start()
18 t2.start()
19 
20 t1.join()
21 t2.join()
22 
23 # a =  1000

thread_global

pythonNet08
pythonNet08

 1 import threading 
 2 from time import sleep 
 3 
 4 s = None    #共享资源
 5 
 6 e = threading.Event()   #创建事件对象
 7 
 8 def bar():
 9     print("呼叫foo")
10     global s 
11     s = "天王盖地虎"
12 
13 def foo():
14     print("等口令")
15     sleep(2)
16     if s == "天王盖地虎":
17         print("宝塔镇河妖")
18     else:
19         print("打死他")
20     e.set() # 设置事件
21 
22 def fun():
23     print("呵呵....")
24     sleep(1)
25     e.wait()    # 事件阻塞函数
26     global s 
27     s = "小鸡炖蘑菇"
28 
29 b = threading.Thread(target = bar)  # 创建事件对象
30 f = threading.Thread(target = foo)
31 t = threading.Thread(target = fun)
32 
33 b.start()
34 f.start()
35 t.start()
36 
37 b.join()
38 f.join()
39 t.join()
40 
41 # 呼叫foo
42 # 等口令
43 # 呵呵....
44 # 宝塔镇河妖

e = threading.Event()

线程锁 Lock

lock = threading.Lock() 创建锁对象
lock.acquire() 上锁
lock.release() 解锁

with lock 上锁

pythonNet08
pythonNet08

 1 import threading 
 2 
 3 a = b = 0 
 4 
 5 lock = threading.Lock()    # 创建锁对象
 6 
 7 def value():
 8     while True:
 9         lock.acquire()    # 上锁
10         if a != b:
11             print("a = %d,b = %d"%(a,b))
12         lock.release()    # 解锁
13 
14 t = threading.Thread(target = value)    # 创建线程对象
15 t.start()
16 
17 while True:
18     lock.acquire()    # 上锁
19     a += 1
20     b += 1
21     lock.release()    # 解锁
22 
23 t.join()

lock.acquire()

python线程的GIL问题

GIL (全局解释器锁)

python —》 支持线程操作 —》IO的同步和互斥 –》 加锁 —-》 超级锁,给解释器加锁

后果:一个解释器,同一时刻只解释一个线程,此时其他线程需要等待。大大降低了python线程的执行效率

python GIL问题解决方案
* 修改c解释器
* 尽量使用多进程进行并行操作
* python线程可以用在高延迟多阻塞的IO情形
* 不使用cpython  c# java做解释器

效率测试

分别测试 多进程 多线程 单进程执行相同的IO操作和CPU

pythonNet08
pythonNet08

 1 #计算密集
 2 def count(x,y):
 3     c = 0
 4     while c < 7000000:
 5         x += 1
 6         y += 1
 7         c += 1
 8 
 9 #io密集
10 def write():
11     f = open("test.txt",'w')
12     for x in range(2000000):
13         f.write("hello world\n")
14     f.close()
15 
16 def read():
17     f = open("test.txt")
18     lines = f.readlines()
19     f.close()

View Code

操作的时间

pythonNet08
pythonNet08

 1 #单进程程序
 2 from test import *
 3 import time 
 4 
 5 # t = time.time()
 6 # for i in range(10):
 7 #     count(1,1)
 8 # print("Line cpu:",time.time() - t)
 9 
10 
11 t = time.time()
12 for i in range(10):
13     write()
14     read()
15 print("Line IO:",time.time() - t)

View Code

Line cpu: 8.15166711807251
Line IO: 6.841825246810913

pythonNet08
pythonNet08

 1 from test import * 
 2 import threading 
 3 import time 
 4 
 5 counts = []
 6 
 7 t = time.time()
 8 
 9 for x in range(10):
10     th = threading.Thread(target = count,args = (1,1))
11     th.start()
12     counts.append(th)
13 
14 for i in counts:
15     i.join()
16 print("Thread cpu",time.time() - t)

View Code

pythonNet08
pythonNet08

 1 from test import * 
 2 import threading 
 3 import time 
 4 
 5 counts = []
 6 
 7 def io():
 8     write()
 9     read()
10 
11 t = time.time()
12 
13 for x in range(10):
14     th = threading.Thread(target = io)
15     th.start()
16     counts.append(th)
17 
18 for i in counts:
19     i.join()
20 print("Thread IO",time.time() - t)

View Code

Thread cpu 8.414522647857666
Thread IO 6.023292541503906

pythonNet08
pythonNet08

 1 from test import * 
 2 import multiprocessing 
 3 import time 
 4 
 5 counts = []
 6 
 7 t = time.time()
 8 
 9 for x in range(10):
10     th = multiprocessing.Process\
11     (target = count,args = (1,1))
12     th.start()
13     counts.append(th)
14 
15 for i in counts:
16     i.join()
17 print("Process cpu",time.time() - t)

View Code

pythonNet08
pythonNet08

 1 from test import * 
 2 import multiprocessing 
 3 import time 
 4 
 5 counts = []
 6 
 7 def io():
 8     write()
 9     read()
10 
11 t = time.time()
12 
13 for x in range(10):
14     th = multiprocessing.Process(target = io)
15     th.start()
16     counts.append(th)
17 
18 for i in counts:
19     i.join()
20 print("Process IO",time.time() - t)

View Code

Process cpu 4.079084157943726
Process IO 3.2132551670074463

进程和线程的区别和联系

1.两者都是多任务编程的方式,都能够使用计算机的多核
2.进程的创建删除要比线程消耗更多的计算机资源
3.进程空间独立,数据安全性好,有专门的进程间通信方法
4.线程使用全局变量通信,更加简单,但是需要同步互斥操 作
5. 一个进程可以包含多个线程,线程共享进程的空间资源
6. 进程线程都独立执行,有自己的特有资源如属性,id, 命令集等

使用情况:
* 一个进程中并发任务比较多,比较简单,适合使用多线程
* 如果数据程序比较复杂,特别是可能多个任务通信比较多 的时候,要考虑到使用线程同步互斥的复杂性
* 多个任务存在明显差异,和功能分离的时候没有必要一定 写入到一个进程中
* 使用python考虑线程GIL问题

要求:
1. 进程线程的区别和关系
2. 进程间都信方式都用过哪些,有什么特点
3. 同步和互斥是怎么回事,你都用哪些方法实现了同步互斥
4. 什么是僵尸进程,怎么处理的
5. python线程的效率怎么样?GIL是怎么处理的

服务器模型

硬件服务器 : 主机 集群
厂商 : IBM HP 联想 浪潮

软件服务器 :编写的服务端程序,依托硬件服务器运行。 提供给用户一定的功能服务

服务器种类

webserver —》 网络的后端应用程序,提供数据处理和逻辑处理
httpserver —> 接受http请求,返回http响应

邮箱服务器 —》 处理邮件请求,进行邮件收发

文件服务器 –》提供文件的上传下载存储

功能实现 : 网络连接,逻辑处理,数据运算,数据交互
协议实现,网络数据传输。。。。

模型结构 : C/S 客户端服务器模型
B/S 浏览器服务器模型

服务器目标:处理速度更快,数据安全性更强,并发量更高

硬件 : 更高的配置,更好的硬件搭配,更高的网络速度
更多的主机,网络安全投入

软件:占有更少的计算机资源,更稳定的运行效率,更流畅的速度,更强大的算法,更合理的技术搭配

网络服务器基础

循环服务器 : 单进程程序,循环接受客户请求,处理请求。处理完毕再接受下一个请求。

特点 : 每次只能处理一个客户端请求;如果客户端长期占有服务器则无法处理其他客户端请求。

优点 : 实现简单,占用资源少
缺点 : 无法同时处理多客户端,体验差
使用情况 : 任务短暂,可以快速完成。udp比tcp更适合循 环

并发服务器 : 能够同时处理多个客户端任务请求

IO 并发 : IO多路复用    协程
优点 : 可以实现IO的并发操作,占用系统资源少
缺点 : 不能监控cpu密集的情况,并能有长期阻塞

多进程/多线程并发:为每个客户端单独提供一个进程/ 线程处理客户端请求

优点 : 客户端可以长期占有服务器
缺点 : 消耗计算机资源较多

多进程并发模型

使用fork完成并发

1. 创建套接字,绑定,监听
2. 等待接受客户端连接请求
3. 创建新的进程处理客户端请求,父进程继续等待连接其他客户端
4. 客户端退出,对应子进程结束

pythonNet08
pythonNet08

 1 from socket import *
 2 import os,signal,sys,time  
 3 
 4 FILE_PATH = "/home/tarena/"    #文件库
 5 class TftpServer(object):    #实现功能模块
 6     pass 
 7 
 8 #流程控制,创建套接字,创建并发,方法调用
 9 def main():
10     HOST = '0.0.0.0'
11     PORT = 8888
12     ADDR = (HOST,PORT)
13 
14     sockfd = socket()
15     sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
16     sockfd.bind(ADDR)
17     sockfd.listen(5)
18 
19     signal.signal(signal.SIGCHLD,signal.SIG_IGN)
20 
21     while True:
22         try: 
23             connfd,addr = sockfd.accept()
24         except KeyboardInterrupt:
25             sockfd.close()
26             sys.exit("服务器退出")
27         except Exception as e:
28             print(e)
29             continue
30         print("客户端登录:",addr)
31 
32         #创建父子进程
33         pid = os.fork()    # 子进程处理客户端请求,父进程等待其他客户端连接
34 
35         if pid == 0:
36             sockfd.close()
37             tftp = TftpServer()  # __init__传参
38             while True:
39                 data = connfd.recv(1024).decode()
40                 if data == "list":
41                     tftp.do_list()
42                 elif data == 'get':
43                     tftp.do_get()
44                 elif data == 'put':
45                     tftp.do_put()
46                 elif data == 'quit':
47                     print("客户端退出")
48                     sys.exit(0)
49         else:
50             connfd.close()
51             continue
52 
53 if __name__ == "__main__":
54     main()

tftp_server

pythonNet08
pythonNet08

 1 from socket import *
 2 import sys 
 3 import time 
 4 
 5 class TftpClient(object):    #实现各种功能请求
 6     pass 
 7 #创建套接字建立连接
 8 def main():
 9     if len(sys.argv) < 3:
10         print("argv is error")
11         return
12     HOST = sys.argv[1]
13     PORT = int(sys.argv[2])
14     ADDR = (HOST,PORT)
15 
16     sockfd = socket()
17     sockfd.connect(ADDR)
18 
19     tftp = TftpClient()   #__init__是否需要传参
20 
21     while True:
22         print("打印界面")
23 
24         cmd = input("输入命令>>")
25 
26         if cmd == "list":
27             tftp.do_list()
28 
29 if __name__ == "__main__":
30     main()

tftp_client

tftp 文件服务器

项目功能 :

* 客户端有简单的页面命令提示
* 功能包含:
1. 查看服务器文件库中的文件列表(普通文件)
2. 可以下载其中的某个文件到本地
3. 可以上传客户端文件到服务器文件库

* 服务器需求 :1. 允许多个客户端同时操作
2.每个客户端可能回连续发送命令

技术分析:
1. tcp套接字更适合文件传输
2. 并发方案 —》 fork 多进程并发
3. 对文件的读写操作
4. 获取文件列表 —-》 os.listdir()
粘包的处理

整体结构设计
1. 服务器功能封装在类中(上传,下载,查看列表)
2. 创建套接字,流程函数调用 main()
3. 客户端负责发起请求,接受回复,展示
服务端负责接受请求,逻辑处理

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/159325.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!