多线程threading

多线程特点:

#线程的并发是利用cpu上下文的切换(是并发,不是并行)
#多线程执行的顺序是无序的
#多线程共享全局变量
#线程是继承在进程里的,没有进程就没有线程
#GIL全局解释器锁
#只要在进行耗时的IO操作的时候,能释放GIL,所以只要在IO密集型的代码里,用多线程就很合适
# 无序的,并发的
def test1(n):
time.sleep()
print('task', n) for i in range():
t = threading.Thread(target=test1,args=('t-%s' % i,))
t.start()
#计算并发所用的时间
import threading
import time def test1(n):
time.sleep()
print('task', n) def test2(n):
time.sleep()
print('task', n) start = time.time()
l = []
t1 = threading.Thread(target=test1, args=(,))
t2 = threading.Thread(target=test1, args=(,))
t1.start()
t2.start()
l.append(t1)
l.append(t2)
for i in l:
i.join()
end = time.time()
print(end - start)

GIL的全称是:Global Interpreter Lock,意思就是全局解释器锁,这个GIL并不是python的特性,他是只在Cpython解释器里引入的一个概念,而在其他的语言编写的解释器里就没有这个GIL例如:Jython,Pypy

为什么会有gil?:

随着电脑多核cpu的出现核cpu频率的提升,为了充分利用多核处理器,进行多线程的编程方式更为普及,随之而来的困难是线程之间数据的一致性和状态同步,而python也利用了多核,所以也逃不开这个困难,为了解决这个数据不能同步的问题,设计了gil全局解释器锁。

说到gil解释器锁,我们容易想到在多线程中共享全局变量的时候会有线程对全局变量进行的资源竞争,会对全局变量的修改产生不是我们想要的结果,而那个时候我们用到的是python中线程模块里面的互斥锁,哪样的话每次对全局变量进行操作的时候,只有一个线程能够拿到这个全局变量;看下面的代码:

import threading
global_num = def test1():
global global_num
for i in range():
global_num += print("test1", global_num) def test2():
global global_num
for i in range():
global_num += print("test2", global_num) t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
在上面的例子里,我们创建了两个线程来争夺对global_num的加一操作,但是结果并非我们想要的,所以我们在这里加入了互斥锁 import threading
import time
global_num = lock = threading.Lock() def test1():
global global_num
lock.acquire()
for i in range():
global_num +=
lock.release()
print("test1", global_num) def test2():
global global_num
lock.acquire()
for i in range():
global_num +=
lock.release()
print("test2", global_num) t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
start_time = time.time() t1.start()
t2.start()

多进程multiprocessing

#一个程序运行起来之后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单位,不仅可以通过线程完成多任务,进程也是可以的
#进程之间是相互独立的
#cpu密集的时候适合用多进程

#进程之间不共享
import multiprocessing
from multiprocessing import Pool
import time
import threading
g_num =
def edit():
global g_num
for i in range():
g_num += def reader():
print(g_num) if __name__ == '__main__':
p1 = multiprocessing.Process(target=edit)
p2 = multiprocessing.Process(target=reader())
p1.start()
p2.start()
p1.join()
p2.join()
#多进程并发
import multiprocessing
from multiprocessing import Pool
import time
def test1():
for i in range():
time.sleep()
print('test', i) def test2():
for i in range():
time.sleep()
print('test', i) if __name__ == '__main__':
p1 = multiprocessing.Process(target=test1)
p2 = multiprocessing.Process(target=test2)
p1.start()
p2.start()
#进程池
import multiprocessing
from multiprocessing import Pool
import time
import threading
g_num =
def test1(n):
for i in range(n):
time.sleep()
print('test1', i) def test2(n):
for i in range(n):
time.sleep()
print('test2', i)
def test3(n):
for i in range(n):
time.sleep()
print('test3', i) def test4(n):
for i in range(n):
time.sleep()
print('test4', i) if __name__ == '__main__':
pool = Pool()#把进程声明出来括号里不写东西说明无限制,如果写数字,就是最大的进程数
pool.apply_async(test1,(,))#用pool去调用函数test1,参数为10格式为(,)
pool.apply_async(test2,(,))#用pool去调用函数test2,参数为10格式为(,)
pool.apply_async(test3,(,))#用pool去调用函数test3,参数为10格式为(,)
pool.apply_async(test4,(,))#用pool去调用函数test4,参数为10格式为(,)
pool.close()#close必须在join的前面
pool.join()

协程并发(gevent)

# 异步IO
# 进程是资源分配的单位
# 线程是操作系统调度的单位
# 进程切换需要的资源最大,效率低
# 线程切换需要的资源一般,效率一般
# 协程切换任务资源很小,效率高
# 多进程、多线程根据cpu核数不一样可能是并行的,但是协成在一个线程中
#协程,自动切换
import gevent,time
from gevent import monkey
monkey.patch_all()
def test1():
for i in range():
time.sleep()
print('test1', ) def test2():
for i in range():
time.sleep()
print('test2', ) g1 = gevent.spawn(test1)
g2 = gevent.spawn(test2)
g1.join()            #开启
g2.join()
#server端
import gevent
from gevent import socket, monkey
monkey.patch_all()
def server_recv_conn(port):
s = socket.socket()
s.bind(('0.0.0.0', port))
s.listen()
while True:
conn, addr = s.accept()
g = gevent.spawn(recv_request, conn)
g.join()
def recv_request(conn):
while True:
data = conn.recv()
data = data.decode('utf-8')
print("recv:", data)
conn.send(data.upper().encode('utf-8')) if __name__ == '__main__':
server_recv_conn() #client端
import socket HOST = 'localhost'
PORT =
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
msg = input("==>:")
s.send(msg.encode('utf-8'))
data = s.recv()
print('接收:', data.decode('utf-8'))
s.close()
 

python第八章:多任务--小白博客的更多相关文章

  1. python之yagmail模块--小白博客

    yagmail 实现发邮件 yagmail 可以简单的来实现自动发邮件功能. 安装 pip install yagmail 简单例子 import yagmail #链接邮箱服务器 yag = yag ...

  2. 这几天有django和python做了一个多用户博客系统(可选择模板)

    这几天有django和python做了一个多用户博客系统(可选择模板) 没完成,先分享下 断断续续2周时间吧,用django做了一个多用户博客系统,现在还没有做完,做分享下,以后等完善了再慢慢说 做的 ...

  3. python环境变量配置 - CSDN博客

    一.下载: 1.官网下载python3.0系列(https://www.python.org/) 2.下载后图标为: 二.安装: Window下: 1.安装路径: 默认安装路径:C:\python35 ...

  4. Python爬虫简单实现CSDN博客文章标题列表

    Python爬虫简单实现CSDN博客文章标题列表 操作步骤: 分析接口,怎么获取数据? 模拟接口,尝试提取数据 封装接口函数,实现函数调用. 1.分析接口 打开Chrome浏览器,开启开发者工具(F1 ...

  5. python网络爬虫 新浪博客篇

    上次写了一个爬世纪佳缘的爬虫之后,今天再接再厉又写了一个新浪博客的爬虫.写完之后,我想了一会儿,要不要在博客园里面写个帖子记录一下,因为我觉得这份代码的含金量确实太低,有点炒冷饭的嫌疑,就是把上次的代 ...

  6. 用Python和Django实现多用户博客系统(二)——UUBlog

    这次又更新了一大部分功能,这次以app的形式来开发. 增加博客分类功能:博客关注.推荐功能(ajax实现) 增加二级频道功能 更多功能看截图及源码,现在还不完善,大家先将就着看.如果大家有哪些功能觉的 ...

  7. 在 Windows Azure 网站上使用 Django、Python 和 MySQL:创建博客应用程序

    编辑人员注释:本文章由 Windows Azure 网站团队的项目经理 Sunitha Muthukrishna 撰写. 根据您编写的应用程序,Windows Azure 网站上的基本Python 堆 ...

  8. Python开发【项目】:博客后台

    概述 通过自己写的博客后台代码.思路,来与武sir的代码进行一个差异化的比较,记录之间的差距,改善以后写代码的思路 博客后台这个项目,对之前Django学习的各个知识点都有涉及到,非常重要 用户登录验 ...

  9. python关于Django搭建简单博客项目(详解一)

    上一篇我们说了如何搭建简易博客网站,下面我们来进行详细解答.本文没有特定顺序,请结合上一篇和源代码参照学习. 相关源代码和解析请参看:https://github.com/Cheng0829/mysi ...

随机推荐

  1. WSL优化 (Windows Subsystem for Linux) Linux子系统优化配置

    目录 wsl优化 (Windows Subsystem for Linux) Linux子系统优化 1. 永久修改wsl终端字体 2. 修改Linux终端配色 3. 添加WSL到右键菜单 wsl优化 ...

  2. web前端(10)—— 浮动,清除默认样式

    文档流 web页面和ps等设计软件有本质的区别,web 网页的制作,是个“流”,从上而下 ,像 “织毛衣”,就跟编程语言一样,都是由上而下 而设计软件 ,想往哪里画东西,就去哪里画 文档流带来的最明显 ...

  3. sqlserver中分区函数 partition by与 group by 区别 删除关键字段重复列

    partition  by关键字是分析性函数的一部分,它和聚合函数(如group by)不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录, partition  by ...

  4. Lua中的#

    Lua中的 对字符串来说,#取字符串的长度,但对于table需要注意. lua的table可以用数字或字符串等作为key, #号得到的是用整数作为索引的最开始连续部分的大小, 如果t[1] == ni ...

  5. CentOS 7.0下安装Python3.6

    CentOS 7.0自带Python2.7 安装Python3.6步骤 1.安装依赖 yum install -y zlib-devel bzip2-devel openssl-devel ncurs ...

  6. 4.9Python数据处理篇之Matplotlib系列(九)---子图分布

    目录 目录 前言 (一)subplot()方法 ==1.语法说明== ==2.源代码== ==3.输出效果== (二)subplot2grid方法 ==1.语法说明== ==2.源代码== ==3.展 ...

  7. Cassandra联手Spark 大数据分析将迎来哪些改变?

    2014Spark峰会在美国旧金山举行,与会数据库平台供应商DataStax宣布,与Spark供应商Databricks合作,在它的旗舰产 品 DataStax Enterprise 4.5 (DSE ...

  8. Java 8 新特性:2-消费者(Consumer)接口

    (原) 在上一篇,用到过这样一个方法: list.forEach(new Consumer<Integer>() { @Override public void accept(Intege ...

  9. Oracle hint之ORDERED和USE_NL

    Hint:ORDERED和USE_NL ORDERED好理解,就是表示根据 from 后面表的顺序join,从左到右,左边的表做驱动表 use_nl(t1,t2):表示对表t1.t2关联时采用嵌套循环 ...

  10. 【转】联普多WAN口路由器是否可以设置叠加带宽

    TP-link联普是全球领先的通讯供应厂商之一,那么你是否知道联普多WAN口路由器可以设置叠加带宽吗?下面是学习啦小编整理的一些关于联普多WAN口路由器是否可以设置叠加带宽的相关资料,供你参考. 联普 ...