python学习道路(day10note)(线程,进程)
1.计算机的发展史
看alex的博客吧,了解一下可以了
2.线程与GIL简介
#线程 #一道单一的指令的控制流,寄生在进程中 #单一进程里的多个线程是共享数据的 #多个线程涉及修改共享数据的时候需要枷锁,看的时候不需要 #GIL global interperter lock 全局锁 #有多少个cpu,启动多少个线程,python执行的时候只会在同一时刻只允许一个线程运行
3.多线程的写法
#多线程代码 简单
# import threading
# import time
# def run(n):
# time.sleep(1)
# print('thread>>>:',n)
#
# t1 = threading.Thread(target=run,args=(1,)) #分支线程
# t1.start()
# print('----------------fengexian') #主线 因为主线更快,所以先显示
# t2 = threading.Thread(target=run,args=(2,))#分之线程
# t2.start()
#多线程代码 并发量高
# print("多线程代码 并发量高")
# import threading
# import time
# def run(n):
# time.sleep(1)
# print('thread>>>:',n)
# for i in range(10):
# t = threading.Thread(target=run,args=(i,))
# t.start()
#多线程代码里面一些常用语句
# import threading
# import time
# def run(n):
# time.sleep(1)
# print(threading.get_ident()) #可以理解一个线程号,但是在该线程中唯一的,但是在系统中不一定唯一
# print('thread>>>:',n)
# print(threading.current_thread()) 打印当前正在运行线程的实例
# for i in range(10):
# t = threading.Thread(target=run,args=(i,))
# t.start()
# t.setName("t-"%i) 更改线程名
# print(t.getName()) #线程名
# print(threading.active_count()) #活跃的线程数统计
# print(threading.current_thread()) 打印主线程的实例
#主线程死了相当于程序退出了,其他的线程是平行的。所以没关系
4.通过类的方式继承启用多线程
#通过类的方式继承启用多线程 一般不这么写
# print("#通过类的方式继承启用多线程")
# 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()
5.线程等待,就是主线程需要等待分支线程结束才继续执行
#线程等待
# import threading
# import time
# def run(n):
# time.sleep(1)
# print("thread:::",n)
# a_list = []
# for i in range(10):
# a = threading.Thread(target=run,args=(i,))
# a.start()
# a_list.append(a)
# # a.join() #相当于串行 但是我需要线程都结束才走主线程
# for a in a_list:
# a.join() #把等待线程结束放这里,相当于等待全部线程结束
# #必须用for循环,直接放在外面不能保证每个线程都执行完
# print("--main thread--")
6.守护线程,当主线程挂了,分支线程也会相应的结束
#主线程死了,线程就该停了 守护进程的概念
# import threading
# import time
# def run(n):
# time.sleep(1)
# print("thread:::",n)
# for i in range(10):
# a = threading.Thread(target=run,args=(i,))
# a.setDaemon(True) #设置为守护线程 当主线程执行完,不管线程结没结束都退出
# a.start()
# print("--main thread--")
7.线程锁(普通锁LOCK,递归锁RLOCK),为了避免出现同时更改一个共享数据发生错乱
#线程锁 防止多个线程修改同一个共享数据
#一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况?
#此代码没有出现混乱的问题,就是本来应该是10而显示只有 8 9 这个样子
#一定要加锁
# import threading
# import time
# def run(n):
# global num
# l.acquire() #获取锁
# num +=1
# time.sleep(1) #修改完数据之后,立刻就把锁释放,因为只要你一锁,只要全局需要等你的数据,就整个程序卡住了,就出现串行了
# l.release() #释放锁
# # time.sleep(1) #如果把这个放到释放锁上面,那就成为串行了。
# print("thread:::",n)
#
# def run2():
# count = 0
# while num<9:
# print('-----',count)
# count += 1
#
# num = 0
# l = threading.Lock() #声明一把锁
# a_list = []
# for i in range(10):
# a = threading.Thread(target=run,args=(i,))
# a.start()
# a_list.append(a)
#
# a2 = threading.Thread(target=run2)
# a2.start()
# for t in a_list:
# t.join()
#
# print("--main thread--")
# print(num)
#RLock(递归锁)就是在一个大锁中还要再包含子锁
# import threading, time
#
# def run1():
# print("grab the first part data")
# lock.acquire()
# global num
# num += 1
# lock.release()
# return num
#
# def run2():
# print("grab the second part data")
# lock.acquire()
# global num2
# num2 += 1
# lock.release()
# return num2
#
# def run3():
# lock.acquire()
# res = run1()
# print('--------between run1 and run2-----')
# res2 = run2()
# lock.release()
# print(res, res2)
#
# if __name__ == '__main__':
#
# num, num2 = 0, 0
# lock = threading.RLock() #如果Rlock 换成lock 就会错乱了
# for i in range(10):
# t = threading.Thread(target=run3)
# t.start()
#
# while threading.active_count() != 1:
# print(threading.active_count())
# else:
# print('----all threads done---')
# print(num, num2)
8.GIL全局解释其锁和用户级别的Lock的区别
#GIL VS LOCK #GIL 全局解释器锁,作用是保证在同一时刻只有一个线程真正在运行 #GIL 解释器自己的锁,为了解决内存回收机制,很有可能当内存清除的时候会有线程调用它才加的锁 #GIL 和用户Lock是不一样的锁,没有任何关系
9.信号量
# Semaphore(信号量)
# 互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。
#改代码执行后结果为五个五个出
# import threading, time
# def run(n):
# semaphore.acquire()
# time.sleep(1)
# print("run the thread: %s\n" % n)
# semaphore.release()
#
# if __name__ == '__main__':
#
# num = 0
# semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行
# for i in range(20):
# t = threading.Thread(target=run, args=(i,))
# t.start()
#
# while threading.active_count() != 1:
# pass # print threading.active_count()
# else:
# print('----all threads done---')
# print(num)
10.定时任务
#定时任务 Timer 3秒之后运行这个线程
# import threading
# def hello():
# print("hello, world")
#
# t = threading.Timer(3.0, hello)
# t.start() # after 30 seconds, "hello, world" will be printed
11.events 线程间的交互
#Events 线程间的交互
#通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则。
#可以当做线程内部的一个标志,当这个标志发生变化,就说明该线程干完了
#红绿灯
# import threading,time
#
# def ligher():
# count = 0
# while True:
# if count < 30:
# if not event.is_set(): #如果没被set我就set
# event.set()
# print("\033[32m;green light\033[0m")
# elif count < 34:
# print("\033[33m;yellow light\033[0m")
# elif count < 60:
# if event.is_set():
# event.clear()
# print("\033[31m;red light\033[0m")
# else:
# count = 0
# count += 1
# time.sleep(0.2)
# def car(n):
# count = 0
# while True:
# event.wait()
# print("car [%s] dududu..." % n)
# count += 1
# time.sleep(1)
#
# event = threading.Event()
# t = threading.Thread(target=ligher)
# t.start()
# c1 = threading.Thread(target=car,args=(1,))
# c1.start()
12.队列
#队列 Queue
#先进先出 FIFO first in first out 常规
#后入先出 last in first out
#不按顺序出,优先级
#先进先出队列
# import queue
# q = queue.Queue()
# q.put(1)
# q.put(2)
# q.put(3)
# q.put('alex')
# print(q.qsize()) #数量
# print(q.get()) #取数
# print(q.empty()) #做一个判断是不是空而已不是清空
# print(q.get())
# print(q.full()) #判断队列会不会满 如果满了,就会阻塞了,q = queue.Queue(maxsize=2),等于2的时候就会返回TRUE
# q.put_nowait(4) #如果满了就直接报错了
#先进后出队列
# import queue
# q = queue.LifoQueue()
# q.put(1)
# q.put(2)
# q.put(3)
# q.put('alex')
# print(q.get())
#优先级队列
# import queue
# q = queue.PriorityQueue()
# q.put([3,'joker'])
# q.put([2,'lili'])
# q.put([1,'alex'])
# print(q.get()) #1 2 3代表优先级,数字越小权重越大 列表,元祖都可以
13.生产者与消费者模型 就是为了解决供不应求,供过于求的时候
#生产者消费者模型 就是为了解决 线程产生和处理线程的速度不一致问题
#在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
#为什么要使用生产者和消费者模式
#在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据
#同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
#什么是生产者消费者模式
#生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。
#生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
#吃骨头
#就是为了解决供不应求,供大于求,最大一个特点程序解耦合,添加生产者不会影响消费者,添加消费者不会影响生产者。提高程序运行效率
# import threading,time
# import queue
# def producer(name):
# count = 0
# while True:
# if q.qsize() < 5:
# print("%s生成了骨头" %name,count)
# q.put(count)
# count+=1
# time.sleep(3)
#
# def consumer(n):
# while True:
# print("%s 取到骨头并吃了它" % n, q.get())
# time.sleep(0.5)
#
# q = queue.Queue(maxsize=4)
#
# p = threading.Thread(target=producer,args=('joker',))
# p2 = threading.Thread(target=producer,args=('alex',))
# c = threading.Thread(target=consumer,args=('lili',))
# p.start()
# p2.start()
# c.start()
#消费完任务之后都要给生产者回执,当生产者回执都结束了,就可以结束了 例如发邮件 转账
# import threading,time
# import queue
# def producer(name):
# count = 0
# for i in range(10):
# print("%s生成了骨头" %name,count)
# q.put(count)
# count+=1
# time.sleep(0.3)
# q.join()
# print("所有骨头都被吃了")
# def consumer(n):
# while True:
# print("%s 取到骨头并吃了它" % n, q.get())
# time.sleep(0.5)
# q.task_done() # 代表我吃完了,就像邮件回执,代表你肯定吃了,肯定回执邮件,这个任务你干完了
# q = queue.Queue(maxsize=4)
# p = threading.Thread(target=producer,args=('joker',))
# c = threading.Thread(target=consumer,args=('lili',))
# p.start()
# c.start()
14.多进程
#多进程multiprocessing
#绕过GIL 例子。八核八个进程,每个进程是个线程
# from multiprocessing import Process
# import time
#
# def f(name):
# time.sleep(2)
# print('hello', name)
#
# if __name__ == '__main__':
# for i in range(10):
# p = Process(target=f, args=('bob',))
# p.start()
# # p.join() #打开就是串行出来hello bob
#多进程的用法
# from multiprocessing import Process
# import os,time
# def info(title):
# print(title)
# print('module name:', __name__)
# print('parent process:', os.getppid()) #父id
# print('process id:', os.getpid()) #当前Id
# print("\n\n")
#
# def f(name):
# info('\033[31;1mfunction f\033[0m')
# print('hello', name)
# time.sleep(10)
#
# if __name__ == '__main__':
# info('\033[32;1mmain process line\033[0m')
# p = Process(target=f, args=('bob',))
# p.start()
# p.join()
15.进程间通讯,Queue,pipe 进程数据交互,并没有改变数据,真正可以改变数据的用manager
#进程间通讯
#不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:
#Queues 使用方法跟threading里的queue差不多 但是线程内存共享的,进程不行
# from multiprocessing import Process, Queue
#
# def f(q):
# q.put([42, None, 'hello'])
#
# if __name__ == '__main__':
# q = Queue()
# p = Process(target=f, args=(q,))
# p.start()
# print(q.get()) # prints "[42, None, 'hello']"
# p.join()
#Pipes 管道 儿子发,父亲收 当然也可以双向,2个进程间通信
# from multiprocessing import Process, Pipe
#
# def f(conn):
# conn.send([42, None, 'hello']) #这里需要注意,发送数据多次没有什么问题,但是要是收的时候没有数据就会卡住
# print("from parent",conn.recv()) #双向
# conn.close()
#
# if __name__ == '__main__':
# parent_conn, child_conn = Pipe() #生成管道
# p = Process(target=f, args=(child_conn,))
# p.start()
# print(parent_conn.recv()) # prints "[42, None, 'hello']"
# parent_conn.send("hello son") #双向
# p.join()
#Queues 和 Pipe 解决了2个进程间的传递并没有解决2个进程之间修改数据
#Manager
# from multiprocessing import Process, Manager
#
# def f(d, l,): #def f(d, l, n,): 加n为了字典效果
# # d[n] = n #为了字典效果
# d[1] = '1'
# d['2'] = 2
# d[0.25] = None
# l.append(2) #每次进程加个2
# #l.append(n) 为了字典效果
# print(l)
#
# if __name__ == '__main__':
# with Manager() as manager: #打开manager
# d = manager.dict() #生成一个字典
#
# l = manager.list(range(5)) #就是生成了五个列表值 [0, 1, 2, 3, 4]
# p_list = []
# for i in range(10):
# p = Process(target=f, args=(d, l))
# # p = Process(target=f, args=(d, l, i,)) 为了字典效果
# p.start()
# p_list.append(p)
#
# for res in p_list:
# res.join()
#
# print(d)
# print(l)
16.进程同步
#进程同步 就是Lock 进程数据独立为什么还需要锁呢
#因为共享一个屏幕,可能输出会乱,加了锁,输出显示就没问题,输入文件也要加锁
# from multiprocessing import Process, Lock
#
# def f(l, i):
# l.acquire()
# try:
# print('hello world', i)
# finally:
# l.release()
#
# if __name__ == '__main__':
# lock = Lock()
#
# for num in range(10):
# Process(target=f, args=(lock, num)).start() 进程自己把锁传进去
17.进程池
进程池 就是同一时间只有多少个进程运行
#进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
# 进程池中有两个方法:
# apply 是串行 ,不要用
# apply_async
# from multiprocessing import Process, Lock, Pool
# import time
#
# def f(num):
# print('hello world %s' % num)
# time.sleep(1)
# return num #返回值告诉主进程我子进程运行结束了么
#
# def callback(data): #这个就是上面f函数的返回值 他的pid永远都是一个,所以只维护一个连接就可以
# print("exec-->:",data)
#
# if __name__ == '__main__':
# lock = Lock()
#
# pool = Pool(processes=5) #
# for num in range(100):
# pool.apply_async(func=f, args=(num,),callback=callback)
# pool.close() #添加完了必须告诉程序地址池我加完了
# pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
18.paramiko 简单的ssh模块
#paramiko 模块
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #第一次连接在不在自己本机上,不在自己就加上去
# 连接服务器
ssh.connect(hostname=')
# 执行命令 返回三个值
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
print(result.decode())
# 关闭连接
ssh.close()
python学习道路(day10note)(线程,进程)的更多相关文章
- python学习笔记12 ----线程、进程
进程和线程的概念 进程和线程是操作系统中两个很重要的概念,对于一般的程序,可能有若干个进程,每一个进程有若干个同时执行的线程.进程是资源管理的最小单位,线程是程序执行的最小单位(线程可共享同一进程里的 ...
- python学习笔记11 ----线程、进程、协程
进程.线程.协程的概念 进程和线程是操作系统中两个很重要的概念,对于一般的程序,可能有若干个进程,每一个进程有若干个同时执行的线程.进程是资源管理的最小单位,线程是程序执行的最小单位(线程可共享同一进 ...
- Python学习笔记9-多线程和多进程
一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...
- python之并发编程(线程\进程\协程)
一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...
- python学习笔记之线程、进程和协程(第八天)
参考文档: 金角大王博客:http://www.cnblogs.com/alex3714/articles/5230609.html 银角大王博客:http://www.cnblogs.com/wup ...
- 4月27日 python学习总结 GIL、进程池、线程池、同步、异步、阻塞、非阻塞
一.GIL:全局解释器锁 1 .GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的, 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2.GIL的优缺点: 优点: 保 ...
- python学习道路(day11note)(协程,同步与异步的性能区别,url爬网页,select,RabbitMq)
1.协程 #协程 又称微线程 是一种用户的轻量级线程 程序级别代码控制 就不用加机器 #不同函数 = 不同任务 A函数切到B函数没有进行cpu级别的切换,而是程序级别的切换就是协程 yelied #单 ...
- Python一路走来 线程 进程
Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env pytho ...
- python学习笔记——多进程二 进程的退出
1 进程的退出函数的基础语法 1.1 进程的退出函数 进程的退出含有有os._exit([status])和sys.exit([status])两种,从数据包来看,该退出模块仅在linux或者unix ...
随机推荐
- python之路十一
RabbitMQ基本概念RabbitMQ , 是一个使用 erlang 编写的 AMQP (高级消息队列协议) 的服务实现. 简单来说, 就是一个功能强大的消息队列服务.通常我们谈到队列服务, 会有三 ...
- spring aop 环绕通知around和其他通知的区别
前言: spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别: 1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知 是不能决定的,他们只 ...
- git pull request
如何发 PR 以下以 wiki-pages 为例 把项目 fork 到自己名下,然后 clone 到本地 git clone git@code.xiaojukeji.com:yexiliang/wik ...
- VC++ 应用程序无法正常启动0xc0150002
使用VC++开发软件,编译后的程序打不开,弹出错误框: 使用Dpends Walker查看依赖项,没有什么异常. 然后,右键"计算机",选择"管理",打开计 ...
- vux 中popup 组件 Mask 遮罩在最上层问题的解决
1. 问题描述:popup弹出层在遮罩层下面的 2.原因:因为滚动元素和mask遮罩层在同一级,vux框架默认把遮罩层放在body标签下的 3.解决方法:更改一下源码,把mask遮罩层放在popup同 ...
- java学习第三天 数组
java中数组一样存在多维,二维数组,三维数组..... 二维数组的定义 格式: 数据类型 [][] 数组名 = new 数据类型 [][]; 动态初始化 数据类型[][] 数组名 = new 数 ...
- MySQL通过增加用户实现远程连接数据库
命令行进入mysql.exe所在目录 mysql -uroot -padmin 例子: grant all privileges on *.* to joe@localhost identified ...
- 使用eclipse+fiddler+微信web开发者工具调试本地微信页面
前面已经说了调试服务器上的微信页面,放链接:http://www.cnblogs.com/Gabriel-Wei/p/5977850.html 还有fiddler调试链接:http://www.cnb ...
- 【Java EE 学习 33 下】【validate表单验证插件】
一.validate 1.官方网站:http://jqueryvalidation.org/ 2.文档说明:http://jqueryvalidation.org/documentation/ 3.j ...
- Power BI for Office 365(一)移动端应用
此篇来自于微软商业智能网站的官方博客团队发布的Power BI在线资料其中的一部分,完整版地址: http://office.microsoft.com/en-us/office365-sharepo ...