python线程

Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import time def show(arg):
time.sleep(1)
print('thread'+str(arg)) for i in range(10):
t = threading.Thread(target=show, args=(i,))
t.start()

  

上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。

更多方法:

start            线程准备就绪,等待CPU调度
setName 为线程设置名称
getName 获取线程名称
setDaemon 设置为后台线程或前台线程(默认)
如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
join 逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
run 线程被cpu调度后自动执行线程对象的run方法

自定义线程类

import threading
import time class MyThread(threading.Thread):
def __init__(self,num):
threading.Thread.__init__(self)
self.num = num def run(self):#定义每个线程要运行的函数
print("running on number:%s" %self.num)
time.sleep(3) if __name__ == '__main__':
t1 = MyThread(1)
t2 = MyThread(2)
t1.start()
t2.start()

线程锁(Lock、RLock)

由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁 - 同一时刻允许一个线程执行操作。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import time gl_num = 0 def show(arg):
global gl_num
time.sleep(1)
gl_num +=1
print(gl_num) for i in range(10):
t = threading.Thread(target=show, args=(i,))
t.start() print('main thread stop')

使用Lock给线程加锁

#!/usr/bin/env python
#coding:utf-8 import threading
import time gl_num = 0
lock = threading.Lock() #实例化调用线程锁 def Func():
lock.acquire() #获取线程锁
global gl_num
gl_num +=1
time.sleep(1)
print(gl_num)
lock.release() for i in range(10):
t = threading.Thread(target=Func)
t.start()

使用RLock给线程加锁

#!/usr/bin/env python
#coding:utf-8 import threading
import time gl_num = 0
lock = threading.RLock() #实例化调用线程锁 def Func():
lock.acquire() #获取线程锁
global gl_num
gl_num +=1
time.sleep(1)
print(gl_num)
lock.release() #释放线程锁,这里注意,在使用线程锁的时候不能把锁,写在代码中,否则会造成阻塞,看起来“像”单线程 for i in range(10):
t = threading.Thread(target=Func)
t.start()

信号量(Semaphore)

互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

import threading
import time def run(n):
semaphore.acquire()
time.sleep(1)
print('run the thread: %s' %n)
semaphore.release() if __name__ == '__main__': num = 0
semaphore = threading.BoundedSemaphore(5) #最多允许5个线程同时运行 for i in range(10):
t = threading.Thread(target=run,args=(i,))
t.start()  

事件(event)

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。

事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

  • clear:将“Flag”设置为False
  • set:将“Flag”设置为True
#!/usr/bin/env python
# -*- coding:utf-8 -*- import threading def do(event):
print('start')
event.wait()
print('execute') event_obj = threading.Event()
for i in range(10):
t = threading.Thread(target=do, args=(event_obj,))
t.start() event_obj.clear()
inp = input('input:')
if inp == 'true':
event_obj.set()

条件(Condition)

使得线程等待,只有满足某条件时,才释放n个线程 

import threading

def run(n):
con.acquire()
con.wait()
print("run the thread: %s" %n)
con.release() if __name__ == '__main__': con = threading.Condition()
for i in range(10):
t = threading.Thread(target=run, args=(i,))
t.start() while True:
inp = input('>>>')
if inp == 'q':
break
con.acquire()
con.notify(int(inp))
con.release()
import threading
def condition_func():
ret = False
inp = input('>>>')
if inp == '1':
ret = True
return ret def run(n):
con.acquire()
con.wait_for(condition_func)
print("run the thread: %s" %n)
con.release() if __name__ == '__main__':
con = threading.Condition()
for i in range(10):
t = threading.Thread(target=run, args=(i,))
t.start()

Timer

定时器,指定n秒后执行某操作

#1秒钟后打印“hello ,world”
from threading import Timer def hello():
print("hello, world") t = Timer(1, hello)
t.start() # after 1 seconds, "hello, world" will be printed

python进程 

#!/usr/bin/python
from multiprocessing import Process
import threading
import time def foo(i):
print('say hi',i) for i in range(10):
p = Process(target=foo,args=(i,))
p.start()

注意:由于进程之间的数据需要各自持有一份,所以创建进程需要非常大的开销。

进程数据共享

进程各自持有一份数据,默认无法共享数据

进程数据共享的方式一:

#/usr/bin/env python
#coding:utf-8 from multiprocessing import Process
from multiprocessing import queues
import multiprocessing def foo(i,arg):
arg.put(i)
print('say hi',i,arg.qsize()) if __name__ == '__main__':
#li = []
li = queues.Queue(20,ctx=multiprocessing)
for i in range(10):
p = Process(target=foo,args=(i,li,))
#p.daemon = True
p.start()
#p.join()

进程共享数据方法二:

#/usr/bin/env python
#coding:utf-8
#Author:Li Yue Mei from multiprocessing import Process
from multiprocessing import queues
import multiprocessing
from multiprocessing import Array def foo(i,arg):
# arg.put(i)
# print('say hi',i,arg.qsize())
arg[i] = i + 100
for item in arg:
print(item)
print('==========') if __name__ == '__main__':
#li = []
#li = queues.Queue(20,ctx=multiprocessing)
li = Array('i',10)
for i in range(10):
p = Process(target=foo,args=(i,li,))
#p.daemon = True
p.start()
#p.join()

进程共享数据三:

#/usr/bin/env python
#coding:utf-8 from multiprocessing import Process
from multiprocessing import queues
import multiprocessing
from multiprocessing import Manager def foo(i,arg):
# arg.put(i)
# print('say hi',i,arg.qsize())
# arg[i] = i + 100
# for item in arg:
# print(item)
# print('==========')
arg[i] = i + 100
print(arg.values()) if __name__ == '__main__':
#li = []
#li = queues.Queue(20,ctx=multiprocessing)
obj = Manager()
li = obj.dict()
#li = Array('i',10)
for i in range(10):
p = Process(target=foo,args=(i,li,))
#p.daemon = True
p.start()
p.join() #方式二
#方式一
import time
time.sleep(0.1)

协程

线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。

协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。

协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程;

#本质是使用http来发送请求,使用的是socket请求
#pip install gevent from gevent import monkey;monkey.patch_all()
import gevent
import requests def f(url):
print('Get: %s' %url)
resp = requests.get(url) data = resp.text
print('%d bytes received from %s.' %(len(data),url)) gevent.joinall([
gevent.spawn(f,'http://www.python.org/'),
gevent.spawn(f,'http://www.yahoo.com/'),
gevent.spawn(f,'http://www.github.com/'),
])

 

python学习之路网络编程篇(第三篇)的更多相关文章

  1. python学习之路网络编程篇(第四篇)

    python学习之路网络编程篇(第四篇) 内容待补充

  2. python学习之路网络编程篇(第二篇)

    新课程知识的引入:python作用域 #python中无块级别作用域 if 1 == 1 : name = 'alex' print(name) for i in range(10): name = ...

  3. python学习之路网络编程篇(第一篇)socket初识

    什么是socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为socket.socket通常也称为“套接字”,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的 ...

  4. python学习之路网络编程篇(第五篇)-续篇

    Python堡垒机实现之基础知识 一般的堡垒机必须要具备以下5个基本功能: 1.权限控制 2.执行命令 3.上传下载文件 4.远程登录 5.记录操作 权限控制 说明:根据不同的登录用户分配不同的可管理 ...

  5. python学习之路网络编程篇(第五篇)

    paramiko简介 paramiko 是基于Python实现的SSH2远程安装连接,支持认证及秘钥方式.可以实现远程命令执行.文件传输.中间SSH代理等功能. paramiko安装 #!/bin/b ...

  6. python学习之路网络编程篇(第四篇)- 续

    Memcache简介 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速 ...

  7. python学习笔记11 ----网络编程

    网络编程 网络编程需要知道的概念 网络体系结构就是使用这些用不同媒介连接起来的不同设备和网络系统在不同的应用环境下实现互操作性,并满足各种业务需求的一种粘合剂.网络体系结构解决互质性问题彩是分层方法. ...

  8. python学习笔记10 ----网络编程

    网络编程 网络编程需要知道的概念 网络体系结构就是使用这些用不同媒介连接起来的不同设备和网络系统在不同的应用环境下实现互操作性,并满足各种业务需求的一种粘合剂.网络体系结构解决互质性问题彩是分层方法. ...

  9. Python学习之==>Socket网络编程

    一.计算机网络 多台独立的计算机通过网络通信设备连接起来的网络.实现资源共享和数据传递.在同一台电脑上可以将D盘上的一个文件传到C盘,但如果想从一台电脑传一个文件到另外一台电脑上就要通过计算机网络 二 ...

随机推荐

  1. django关闭调试信息,打开内置错误视图

    1 内置错误视图 Django内置处理HTTP错误的视图,主要错误及视图包括: 404错误:page not found视图 500错误:server error视图 400错误:bad reques ...

  2. EFCore CodeFirst 连接MySql

    一.工具及环境 Visual Studio 2017 15.4.3 MySql Navicat for MySQL 二.Entity Framwork Core 2.0 MySql Code Firs ...

  3. Google Cardboard的九轴融合算法——基于李群的扩展卡尔曼滤波

    Google Cardboard的九轴融合算法 --基于李群的扩展卡尔曼滤波 极品巧克力 前言 九轴融合算法是指通过融合IMU中的加速度计(三轴).陀螺仪(三轴).磁场计(三轴),来获取物体姿态的方法 ...

  4. Mac安装opencv指南

      最近接到了新的调研任务.主要是和人脸,各种所谓'AI'相关的.因为这里要处理视频和图像.于是在网上看到很多资料都是关于opencv的所以准备用opencv来开发这些东西.既然要用到opencv.那 ...

  5. java模式之模板模式——抽象类

    模板设计模式(Template ) abstract class Action{ // 定义一个行为类 public static final String WORK = "work&quo ...

  6. LeetCode Binary Search Summary 二分搜索法小结

    二分查找法作为一种常见的查找方法,将原本是线性时间提升到了对数时间范围,大大缩短了搜索时间,具有很大的应用场景,而在LeetCode中,要运用二分搜索法来解的题目也有很多,但是实际上二分查找法的查找目 ...

  7. 数据结构与算法 —— 链表linked list(04)

    我们在上篇文章里面提到了链表的翻转,给定一个链表,对每两个相邻的节点作交换,并返回头节点,今天的这道题是它的升级版,如下: k个一组翻转链表 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链 ...

  8. 用C# (.NET Core) 实现迭代器设计模式

    本文的概念来自深入浅出设计模式一书 项目需求 有两个饭店合并了, 它们各自有自己的菜单. 饭店合并之后要保留这两份菜单. 这两个菜单是这样的: 菜单项MenuItem的代码是这样的: 最初我们是这样设 ...

  9. django 模板继承与重写

    1.模板的继承一般用在别人给我们做好的HTML页面,当我们发现有很多的页面都具有相同的部分,这会我们应该考虑怎么能把他们相同的部分给提取出来,提取出来的部分我们作为一个单独的HTML文件叫做base. ...

  10. java开发----自定义对象,重写equals方法

    javaweb开发中,用到了好多自定义对象,这时候如果不重写equals方法,很多时候都会返回false, 因此我们必须习惯重写这个方法. 重点: 1.equals比较俩对象时比较的是对象引用是否指向 ...