pythonNet08
线程通信
通信方法:多个线程共用进程空间,所以进程的全局变量对进程内线程均可见。线程往往使用全局变量进行通信
注意事项:线程间使用全局变量进行通信,全局变量为共享资源,往往需要同步互斥机制
线程的同步互斥
线程Event
e = threading.Event() 创建事件对象
e.wait([timeout]) 事件阻塞函数
e.set() 设置事件
e.clear() 清除事件
from threading import Thread
from time import sleep
a = 1
def foo():
global a
a = 1000
def bar():
sleep(1)
print("a = ",a)
t1 = Thread(target = foo)
t2 = Thread(target = bar)
t1.start()
t2.start()
t1.join()
t2.join()
# a = 1000
thread_global
import threading
from time import sleep
s = None #共享资源
e = threading.Event() #创建事件对象
def bar():
print("呼叫foo")
global s
s = "天王盖地虎"
def foo():
print("等口令")
sleep(2)
if s == "天王盖地虎":
print("宝塔镇河妖")
else:
print("打死他")
e.set() # 设置事件
def fun():
print("呵呵....")
sleep(1)
e.wait() # 事件阻塞函数
global s
s = "小鸡炖蘑菇"
b = threading.Thread(target = bar) # 创建事件对象
f = threading.Thread(target = foo)
t = threading.Thread(target = fun)
b.start()
f.start()
t.start()
b.join()
f.join()
t.join()
# 呼叫foo
# 等口令
# 呵呵....
# 宝塔镇河妖
e = threading.Event()
线程锁 Lock
lock = threading.Lock() 创建锁对象
lock.acquire() 上锁
lock.release() 解锁
with lock 上锁
import threading
a = b = 0
lock = threading.Lock() # 创建锁对象
def value():
while True:
lock.acquire() # 上锁
if a != b:
print("a = %d,b = %d"%(a,b))
lock.release() # 解锁
t = threading.Thread(target = value) # 创建线程对象
t.start()
while True:
lock.acquire() # 上锁
a += 1
b += 1
lock.release() # 解锁
t.join()
lock.acquire()
python线程的GIL问题
GIL (全局解释器锁)
python ---》 支持线程操作 ---》IO的同步和互斥 --》 加锁 ----》 超级锁,给解释器加锁
后果:一个解释器,同一时刻只解释一个线程,此时其他线程需要等待。大大降低了python线程的执行效率
python GIL问题解决方案
* 修改c解释器
* 尽量使用多进程进行并行操作
* python线程可以用在高延迟多阻塞的IO情形
* 不使用cpython c# java做解释器
效率测试
分别测试 多进程 多线程 单进程执行相同的IO操作和CPU
#计算密集
def count(x,y):
c = 0
while c < 7000000:
x += 1
y += 1
c += 1
#io密集
def write():
f = open("test.txt",'w')
for x in range(2000000):
f.write("hello world\n")
f.close()
def read():
f = open("test.txt")
lines = f.readlines()
f.close()
操作的时间
#单进程程序
from test import *
import time
# t = time.time()
# for i in range(10):
# count(1,1)
# print("Line cpu:",time.time() - t)
t = time.time()
for i in range(10):
write()
read()
print("Line IO:",time.time() - t)
Line cpu: 8.15166711807251
Line IO: 6.841825246810913
from test import *
import threading
import time
counts = []
t = time.time()
for x in range(10):
th = threading.Thread(target = count,args = (1,1))
th.start()
counts.append(th)
for i in counts:
i.join()
print("Thread cpu",time.time() - t)
from test import *
import threading
import time
counts = []
def io():
write()
read()
t = time.time()
for x in range(10):
th = threading.Thread(target = io)
th.start()
counts.append(th)
for i in counts:
i.join()
print("Thread IO",time.time() - t)
Thread cpu 8.414522647857666
Thread IO 6.023292541503906
from test import *
import multiprocessing
import time
counts = []
t = time.time()
for x in range(10):
th = multiprocessing.Process\
(target = count,args = (1,1))
th.start()
counts.append(th)
for i in counts:
i.join()
print("Process cpu",time.time() - t)
from test import *
import multiprocessing
import time
counts = []
def io():
write()
read()
t = time.time()
for x in range(10):
th = multiprocessing.Process(target = io)
th.start()
counts.append(th)
for i in counts:
i.join()
print("Process IO",time.time() - t)
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. 客户端退出,对应子进程结束
from socket import *
import os,signal,sys,time
FILE_PATH = "/home/tarena/" #文件库
class TftpServer(object): #实现功能模块
pass
#流程控制,创建套接字,创建并发,方法调用
def main():
HOST = '0.0.0.0'
PORT = 8888
ADDR = (HOST,PORT)
sockfd = socket()
sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
sockfd.bind(ADDR)
sockfd.listen(5)
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
while True:
try:
connfd,addr = sockfd.accept()
except KeyboardInterrupt:
sockfd.close()
sys.exit("服务器退出")
except Exception as e:
print(e)
continue
print("客户端登录:",addr)
#创建父子进程
pid = os.fork() # 子进程处理客户端请求,父进程等待其他客户端连接
if pid == 0:
sockfd.close()
tftp = TftpServer() # __init__传参
while True:
data = connfd.recv(1024).decode()
if data == "list":
tftp.do_list()
elif data == 'get':
tftp.do_get()
elif data == 'put':
tftp.do_put()
elif data == 'quit':
print("客户端退出")
sys.exit(0)
else:
connfd.close()
continue
if __name__ == "__main__":
main()
tftp_server
from socket import *
import sys
import time
class TftpClient(object): #实现各种功能请求
pass
#创建套接字建立连接
def main():
if len(sys.argv) < 3:
print("argv is error")
return
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT)
sockfd = socket()
sockfd.connect(ADDR)
tftp = TftpClient() #__init__是否需要传参
while True:
print("打印界面")
cmd = input("输入命令>>")
if cmd == "list":
tftp.do_list()
if __name__ == "__main__":
main()
tftp_client
tftp 文件服务器
项目功能 :
* 客户端有简单的页面命令提示
* 功能包含:
1. 查看服务器文件库中的文件列表(普通文件)
2. 可以下载其中的某个文件到本地
3. 可以上传客户端文件到服务器文件库
* 服务器需求 :1. 允许多个客户端同时操作
2.每个客户端可能回连续发送命令
技术分析:
1. tcp套接字更适合文件传输
2. 并发方案 ---》 fork 多进程并发
3. 对文件的读写操作
4. 获取文件列表 ----》 os.listdir()
粘包的处理
整体结构设计
1. 服务器功能封装在类中(上传,下载,查看列表)
2. 创建套接字,流程函数调用 main()
3. 客户端负责发起请求,接受回复,展示
服务端负责接受请求,逻辑处理
pythonNet08的更多相关文章
- python学习菜单
一.python简介 二.python字符串 三.列表 四.集合.元组.字典 五.函数 六.python 模块 七.python 高阶函数 八.python 装饰器 九.python 迭代器与生成器 ...
随机推荐
- Solidity 官方文档中文版 4_Solidity 编程实例
Voting 投票 接下来的合约非常复杂,但展示了很多Solidity的特性.它实现了一个投票合约.当然,电子选举的主要问题是如何赋予投票权给准确的人,并防止操纵.我们不能解决所有的问题,但至少我们会 ...
- 使用 Git Hook 自动部署 Hexo 到个人 VPS
安装 Hexo 既然我的标题都已经那样写了,当然这个小节就不是本篇文章的重点了. 关于 Hexo 的安装跟配置,其实网上已经有很多很多文章了,随便一搜一大把.这里就有一篇超详细的,大家可以参考一下. ...
- hihocoder1513
https://hihocoder.com/problemset/problem/1513 五维偏序问题,直接bitset压位,复杂度O(n^2/32) (本来想写三维偏序,但是cdq不会只好写写五维 ...
- Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制
Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...
- VGG16提取图像特征 (torch7)
VGG16提取图像特征 (torch7) VGG16 loadcaffe torch7 下载pretrained model,保存到当前目录下 th> caffemodel_url = 'htt ...
- UVA-1152 4 Values whose Sum is 0 (二分)
题目大意:在4个都有n个元素的集合中,每个集合选出一个元素,使得4个数和为0.问有几种方案. 题目分析:二分.任选两组求和,剩下两组求和,枚举第一组中每一个和sum,在第二组和中查找-sum的个数,累 ...
- Oracle Sourcing Implementation and Administration Guide(转)
原文地址 Oracle Sourcing Implementation and Administration Guide
- 本地Run Page时报检测到意外的 URL 参数,它将被忽略。
经查,是因为我RUN的时候 Target URL -- http://MY-PC:8988/OA_HTML/runregion.jsp 将MY-PC更改为本地IP即可. 设置方法 Tools - Em ...
- https ddos攻击——由于有了认证和加解密 后果更严重 看绿盟的产品目前对于https的ddos cc攻击需要基于内容做检测
如果web服务器支持HTTPS,那么进行HTTPS洪水攻击是更为有效的一种攻击方式,一方面,在进行HTTPS通信时,web服务器需要消耗更多的资源用来进行认证和加解密,另一方面,一部分的防护设备无法对 ...
- 【hive】时间段为五分钟的统计
问题内容 今天遇到了一个需求,需求就是时间段为5分钟的统计.有数据的时间戳.对成交单量进行统计. 想法思路 因为数据有时间戳,可以通过from_unixtime()来获取具体的时间. 有了具体的时间, ...