Python 线程,进程
Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元
线程不能实现多并发 只能实现伪并发 每次工作 只能是一个线程完成 由于python解释器 原生是c 原生线程 底层都会有一把锁
直接调用线程
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Administrator' 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=(1,)) t1.start() #启动线程 t2.start() #启动另一个线程 print(t1.getName()) #获取线程名 print(t2.getName())
如果需要开启10个线程呢 如何做 for循环
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Administrator' import threading import time def sayhi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__': for i in range(10): t = threading.Thread(target=sayhi,args=(i,)) t.start()
继承调用
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Administrator' import socketserver 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()
更多方法:
- start 线程准备就绪,等待CPU调度
- setName 为线程设置名称
- getName 获取线程名称
- setDaemon 设置为后台线程或前台线程(默认)
如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止 - join 逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
- run 线程被cpu调度后自动执行线程对象的run方法
Join & Daemon
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Administrator' import time import threading def run(n): print('[%s]------running----\n' % n) time.sleep(2) print('--done--') def main(): for i in range(5): t = threading.Thread(target=run,args=[i,]) #time.sleep(1) t.start() #t.join(1) print('starting thread', t.getName()) m = threading.Thread(target=main,args=[]) #m.setDaemon(True) #将主线程设置为Daemon线程,它退出时,其它子线程会同时退出,不管是否执行完任务 m.start() #m.join(timeout=10) print("---main thread done----")
线程锁
一个进程下可以起到多个进程,多个线程共享父进程的内存空间,也意味着每个线程可以访问同一份数据,此时,如果2个线程同时
要修改一份数据,会出现什么状况?
由于线程之间是进行随机调度,并且每个线程可能只执行N条执行后,CPU接着执行其它线程。所以出现以下问题
#!/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'
未使用锁
加锁后
#!/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()
加锁后
import time import threading def addNum(): global num #在每个线程中都获取这个全局变量 print('--get num:',num ) time.sleep(1) num -=1 #对此公共变量进行-1操作 num = 100 #设定一个共享变量 thread_list = [] for i in range(100): t = threading.Thread(target=addNum) t.start() thread_list.append(t) for t in thread_list: #等待所有线程执行完毕 t.join() print('final num:', num )
未加锁
import time import threading def addNum(): global num #在每个线程中都获取这个全局变量 print('--get num:',num ) time.sleep(1) lock.acquire() #修改数据前加锁 num -=1 #对此公共变量进行-1操作 lock.release() #修改后释放 num = 100 #设定一个共享变量 thread_list = [] lock = threading.Lock() #生成全局锁 for i in range(100): t = threading.Thread(target=addNum) t.start() thread_list.append(t) for t in thread_list: #等待所有线程执行完毕 t.join() print('final num:', num )
加锁后
正常来讲,这个num结果应该是0, 但在python 2.7上多运行几次,会发现,最后打印出来的num结果不总是0,为什么每次运行的结果不一样呢? 哈,很简单,假设你有A,B两个线程,此时都 要对num 进行减1操作, 由于2个线程是并发同时运行的,所以2个线程很有可能同时拿走了num=100这个初始变量交给cpu去运算,当A线程去处完的结果是99,但此时B线程运算完的结果也是99,两个线程同时CPU运算的结果再赋值给num变量后,结果就都是99。那怎么办呢? 很简单,每个线程在要修改公共数据时,为了避免自己在还没改完的时候别人也来修改此数据,可以给这个数据加一把锁, 这样其它线程想修改此数据时就必须等待你修改完毕并把锁释放掉后才能再访问此数据。
*注:不要在3.x上运行,不知为什么,3.x上的结果总是正确的,可能是自动加了锁
线程锁跟远程线程底层锁GIL是没有关联的 两个线程要同时更改一个共享数据很难保证数据的一致性,所以要加上线程锁 等1个线程运行完 在释放锁 保证数据的一致性
Queue队列
- class
queue.
Queue
(maxsize=0) #先入先出
- class
queue.
LifoQueue
(maxsize=0) #last in fisrt out - class
queue.
PriorityQueue
(maxsize=0) #存储数据时可设置优先级的队列
简单的语法命令
import queue q = queue.Queue(maxsize=3) #最大3个 #q.get() #阻塞 #q.get(timeout=3) #3秒后 报异常 queue.Empty q.get_nowait() #报异常 于q.get(timeout=3)是一样的效果
加一点数据 put
import queue q = queue.Queue(maxsize=3) #最大3个 q.put([1,2,3]) #存放一个列表 #q.get() #阻塞 #q.get(timeout=3) #3秒后 报异常 queue.Empty #q.get_nowait() #报异常 于q.get(timeout=3)是一样的效果 data = q.get_nowait() print(data,type(data))
判断最大值是否满了
import queue q = queue.Queue(maxsize=3) #最大3个 q.put([1,2,3]) q.put(1) q.put(2) q.put(3,timeout=2) data = q.get_nowait() #释放一个 q.put(4) #print(data,type(data)) print(q.full()) #q.full()判断是否满
先入后出
q = queue.LifoQueue(maxsize=30) q.put([1,2,3]) q.put(1) q.put(3) print(q.get()) #获取的值为 3
优选级
import queue q = queue.PriorityQueue(maxsize=30) q.put((7,[1,2,3])) q.put((6,1)) q.put((5,3)) print(q.get()) #获取的值为 (5, 3)
生产者消费者
#!/usr/bin/env python #_*_ coding:utf8 _*_ __author__ = 'Administrator' import threading,queue import time def consumer(n): while True: print("consumer [%s] get task: %s" % (n,q.get())) time.sleep(1) q.task_done() def producer(n): count = 1 while True: time.sleep(0.5) #for i in range(2): print("prodcer [%s] produced a new task : %s" %(n,count)) q.put(count) count += 1 q.join() print("all taks has been cosumed by consumers........") l = threading.Lock #相当于服务员 q = queue.Queue() #消费者 c1 = threading.Thread(target=consumer,args=[1,]) c2 = threading.Thread(target=consumer,args=[2,]) c3 = threading.Thread(target=consumer,args=[3,]) #生产者 p = threading.Thread(target=producer,args=["alex",]) p2 = threading.Thread(target=producer,args=["yiyezi",]) p3 = threading.Thread(target=producer,args=["haha",]) #启动 c1.start() c2.start() c3.start() p.start() p2.start() p3.start()
Python 线程,进程的更多相关文章
- python 线程 进程
1.进程与线程优.缺点的比较总言:使用进程和线程的目的,提高执行效率. 进程: 优点:能利用机器的多核性能,同时进行多个操作. 缺点:需要耗费资源,重新开辟内存空间,耗内存. 线程: 优点:共享内存( ...
- python 线程 进程 协程 学习
转载自大神博客:http://www.cnblogs.com/aylin/p/5601969.html 仅供学习使用···· python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和 ...
- python线程进程
多道技术: 多道程序设计技术 所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行.即同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统中的各种硬.软件资源.当一道程序因I/O请 ...
- Python 线程&进程与协程
Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...
- python 线程进程
一 线程的2种调用方式 直接调用 实例1: import threading import time def sayhi(num): #定义每个线程要运行的函数 print("runni ...
- python线程,进程,队列和缓存
一.线程 threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 创建线程的两种方式1.threading.Thread import threading def f1(arg): ...
- python 线程,进程28原则
基于函数实现 from threading import Thread def fun(data, *args, **kwargs): """ :param data: ...
- python 线程/进程模块
线程的基本使用: import threading # ###################### 1.线程的基本使用 def func(arg): print(arg) t = threading ...
- python 线程 进程 标识
s = '%s%s%s%s%s%s%s%s' % ( time.strftime('%Y%m%d %H:%M:%S', time.localtime(time.time())), ' os.getpp ...
- python 线程(一)理论部分
Python线程 进程有很多优点,它提供了多道编程,可以提高计算机CPU的利用率.既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的. 主要体现在一下几个方面: 进程只能在 ...
随机推荐
- 第三章 Netty入门应用
3.1 Netty开发环境的搭建 3.1.1 下载Netty的软件包 3.1.2 搭建Netty应用工程 3.2 Netty服务端开发 3.3 Netty客户端开发 3.4 运行和调试 3.4.1 服 ...
- cpanel导入大数据库(mysql)的方法
phpmyadmin是一件很方便的在线管理MySQL数据库的工具,但对于较大的数据库的导出和导入却很容易出错.特别是导入工作,通常5M已经是它的极限了.这里,主要介绍一下如何通过cPanel导入大型的 ...
- Maven搭建springMVC+spring+hibernate环境
这次不再使用struts2做控制器,采用spring自己的springMVC框架实现. 首先,改写pom.xml文件,不需要struts2的相关jar了. pom.xml <project xm ...
- HttpWebRequest的简单使用
新建新的空网站和一个default.aspx页面测试,实验例子: using System; using System.Collections.Generic; using System.IO; us ...
- UVa 1354 Mobile Computing | GOJ 1320 不加修饰的天平问题 (例题 7-7)
传送门1(UVa): https://uva.onlinejudge.org/external/13/1354.pdf 传送门2(GOJ): http://acm.gdufe.edu.cn/Probl ...
- 修改win7锁定界面背景
Regedit HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Authentication/LogonUI/Backgrou ...
- JVM基础(4)-编译
一.编译过程 不论是物理机还是虚拟机,大部分的程序代码从开始编译到最终转化成物理机的目标代码或虚拟机能执行的指令集之前,都会按照如下图所示的各个步骤进行: (其中绿色的模块可以选择性实现.) 很容易看 ...
- tar的打包-压缩与解压缩,并解压到指定的目录
tar在linux上是常用的打包.压缩.加压缩工具,他的参数很多,折里仅仅列举常用的压缩与解压缩参数 参数: -c :create 建立压缩档案的参数:-x : 解压缩压缩档案的参数:-z : 是否需 ...
- Codeforces Round #256 (Div. 2) B Suffix Structures
Description Bizon the Champion isn't just a bison. He also is a favorite of the "Bizons" t ...
- php 备份数据库
<?php header("Content-type:text/html;charset=utf-8"); //配置信息 $cfg_dbhost = 'loca ...