Python学习-day9 线程
这节内容主要是关于线程的学习
首先要了解的什么是进程,什么是线程
进程与线程
什么是进程(process)?
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。
有了进程为什么还要线程?
进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:
进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。
例如,我们在使用qq聊天, qq做为一个独立进程如果同一时间只能干一件事,那他如何实现在同一时刻 即能监听键盘输入、又能监听其它人给你发的消息、同时还能把别人发的消息显示在屏幕上呢?你会说,操作系统不是有分时么?但我的亲,分时是指在不同进程间的分时呀, 即操作系统处理一会你的qq任务,又切换到word文档任务上了,每个cpu时间片分给你的qq程序时,你的qq还是只能同时干一件事呀。
再直白一点, 一个操作系统就像是一个工厂,工厂里面有很多个生产车间,不同的车间生产不同的产品,每个车间就相当于一个进程,且你的工厂又穷,供电不足,同一时间只能给一个车间供电,为了能让所有车间都能同时生产,你的工厂的电工只能给不同的车间分时供电,但是轮到你的qq车间时,发现只有一个干活的工人,结果生产效率极低,为了解决这个问题,应该怎么办呢?。。。。没错,你肯定想到了,就是多加几个工人,让几个人工人并行工作,这每个工人,就是线程!
什么是线程(thread)?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
进程与线程的区别?
- Threads share the address space of the process that created it; processes have their own address space.
- Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
- Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
- New threads are easily created; new processes require duplication of the parent process.
- Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
- Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes.
Python GIL(Global Interpreter Lock)
无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行。
首先需要明确的一点是GIL
并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL
归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL
这篇文章透彻的剖析了GIL对python多线程的影响,强烈推荐看一下:http://www.dabeaz.com/python/UnderstandingGIL.pdf
Python threading模块
- #Author:Ivor
- import threading
- import time
- def run(n):
- print("task---start,",n)
- time.sleep(1)
- print("task---end",n,threading.current_thread())
- res_list = []
- start_time = time.time()
- #Starting Multiple threads
- for i in range(50):
- t = threading.Thread(target=run,args=("t %s" % i,))
- #set child threads to daemon threads
- t.setDaemon(True)
- t.start()
- res_list.append(t)
- #Main Thread waiting for the child threads
- for r in res_list:
- r.join()
- print("current thread",threading.current_thread())
- print("Running time = ",time.time() - start_time)
- import threading
- 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()
线程锁(互斥锁Mutex)
- #Authon Ivor
- import time
- import threading
- def addNum():
- global num # 在每个线程中都获取这个全局变量
- 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)
RLock(递归锁)
- #Authon Ivor
- 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)
- num, num2 = 0, 0
- lock = threading.RLock() #must be use RLock
- # lock = threading.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)
Semaphore(信号量)
- #Authon Ivor
- import threading
- import time
- def run(n):
- semaphore.acquire()
- print(n)
- time.sleep(1)
- semaphore.release()
- neq = threading.Semaphore(5)
- semaphore = threading.BoundedSemaphore(5)
- for i in range(10):
- t = threading.Thread(target=run,args=(i,))
- t.start()
Events
- #Authon Ivor
- import threading
- import time
- def light():
- count = 0
- #initialize signal
- cond.set()
- while True:
- if count > 5 and count < 10:
- #clear signal
- cond.clear()
- print("\033[41;1mRed light\033[;0m")
- elif count > 10:
- #set signal
- cond.set()
- count = 0
- else:
- print("\033[42;1mGreen light\033[;0m")
- count += 1
- time.sleep(1)
- def car():
- while True:
- time.sleep(1)
- if cond.is_set():
- print("Car gogo...")
- else:
- print("Car stop...")
- #hang on the thread
- cond.wait()
- cond = threading.Event()
- l = threading.Thread(target=light)
- c = threading.Thread(target=car)
- l.start()
- c.start()
不得不提的消息队列
Queue
- #Authon Ivor
- import threading
- import queue
- def producer():
- for i in range(10):
- q.put("骨头 %s" % i)
- print("开始等待所有的骨头被取走...")
- q.join()
- print("所有的骨头被取完了...")
- def consumer(n):
- while q.qsize() > 0:
- print("%s 取到" % n, q.get())
- q.task_done() # 告知这个任务执行完了
- q = queue.Queue()
- p = threading.Thread(target=producer)
- p.start()
- c1 = consumer("李闯")
- import time,random
- import queue,threading
- def Producer(name):
- count = 0
- while count <20:
- time.sleep(random.randrange(3))
- q.put(count)
- print('Producer %s has produced %s baozi..' %(name, count))
- count +=1
- def Consumer(name):
- count = 0
- while count <20:
- time.sleep(random.randrange(4))
- if not q.empty():
- data = q.get()
- print(data)
- print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))
- else:
- print("-----no baozi anymore----")
- count +=1
- q = queue.Queue()
- p1 = threading.Thread(target=Producer, args=('A',))
- c1 = threading.Thread(target=Consumer, args=('B',))
- p1.start()
- c1.start()
还有一个实现自动化运维的模块
Pamamiko
SFTP
- #Authon Ivor
- import paramiko
- #创建一个连接
- conn = paramiko.Transport(('10.0.2.57',22))
- conn.connect(username='root',password='test83@123')
- #通过连接实例,创建一个FTPClient实例
- sftp = paramiko.SFTPClient.from_transport(conn)
- #上传动作
- # sftp.put('D:\\test.xls','/tmp/test.xls')
- #下载动作
- # sftp.get('/tmp/test.xls','D:\\test.xls')
- conn.close()
- #Author:Ivor
- import paramiko
- private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
- transport = paramiko.Transport(('hostname', 22))
- transport.connect(username='wupeiqi', pkey=private_key)
- sftp = paramiko.SFTPClient.from_transport(transport)
- sftp.put('/tmp/location.py', '/tmp/test.py')
- sftp.get('remove_path', 'local_path')
- transport.close()
SSH
- #Authon Ivor
- import paramiko
- #创建SSH实例
- ssh = paramiko.SSHClient()
- #设置不在known_host的主机
- ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
- #建立连接
- ssh.connect(hostname="10.0.2.57",port=22,username="root:",password="test83@123")
- #执行命令,返回标准输入输出错误
- stdin, stdout, stderr = ssh.exec_command("df")
- #读取结果
- result = stdout.read()
- print(result.decode())
- #关闭连接
- ssh.close()
- #Author:Ivor
- #######
- #funtion 1
- #######
- import paramiko
- private_key = paramiko.RSAKey.from_private_key_file('id_rsa')
- ssh = paramiko.SSHClient()
- ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
- ssh.connect(hostname='59.110.23.110', port=22, username='root', pkey=private_key)
- stdin, stdout, stderr = ssh.exec_command('df')
- result = stdout.read()
- print(result.decode())
- ssh.close()
- ########
- #funtion 2
- ########
- import paramiko
- from io import StringIO
- key = '''XXX
- -----END RSA PRIVATE KEY-----'''
- private_key = paramiko.RSAKey(file_obj=StringIO(key))
- transport = paramiko.Transport((XXXX, 22))
- transport.connect(username='root', pkey=private_key)
- ssh = paramiko.SSHClient()
- ssh._transport = transport
- stdin, stdout, stderr = ssh.exec_command('df')
- result = stdout.read()
- transport.close()
- print(result)
Python学习-day9 线程的更多相关文章
- python学习笔记——线程threading (二)重写run()方法和守护进程daemon()
1 run()方法 1.1 单个线程 在threading.Thread()类中有run()方法. from time import ctime,sleep import threading # 定义 ...
- python学习笔记——线程threading (一)
1 线程threading 1.1 基本概述 也被称为轻量级的进程. 线程是计算机多任务编程的一种方式,可以使用计算机的多核资源. 线程死应用程序中工作的最小单元 1.2 线程特点 (1)进程的创建开 ...
- python学习day9
目录 一.队列 二.生产者消费者模型 三.协程 四.select\poll\epoll 五.paramiko 六.mysql API调用 一.队列(queue) 队列分以下三种: class queu ...
- python学习Day9 内存管理
复习 :文件处理 1. 操作文件的三步骤:-- 打开文件:此时该文件在硬盘的空间被操作系统持有 | 文件对象被应用程序持用 -- 操作文件:读写操作 -- 释放文件:释放操作系统对文件在硬盘间的持有 ...
- python 学习分享-线程
多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...
- Python学习之线程
8.5 线程 进程:开辟空间,加载数据,资源单位 线程:流水线,执行代码,执行单位 8.5.1 线程的概念 是操作系统能够进行运算调度的最小单位,线程包含在进程中,是进程中的执行单元,一个进程至少包含 ...
- Python学习之==>线程&&进程
一.什么是线程(thread) 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一个线程指的是进程中一个单一顺序的控制流,一个进程中可以包含多个线程,每条线程并行 ...
- 4月28日 python学习总结 线程与协程
一. 异步与回调机制 问题: 1.任务的返回值不能得到及时的处理,必须等到所有任务都运行完毕才能统一进行处理 2.解析的过程是串行执行的,如果解析一次需要花费2s,解析9次则需要花费18s 解决一: ...
- python学习day9 字符编码和文件处理
1.字符编码 x='上' #unicode的二进制--------->编码-------->gbk格式的二进制 res=x.encode('gbk') #bytes 字节类型 print( ...
随机推荐
- ABAP数据转换规则
数据转换规则: 可以将基本数据类型的源字段内容赋给其它基本数据类型的目标字段(除了数据类型 D 无法赋给数据类型 T,反之亦然).ABAP/4 也支持结构化数据和基本数据对象之间或结构不同的数据对象之 ...
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:2.技术简介之MinaFilter(1)
欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 Filter filter:过滤器?(不知道是不是这么翻译,算了知道意思就好了╮(╯▽╰)╭),这种东西在很多语言中 ...
- javaSe-hashMap
package com.java.chap08.sec05; public class Student { private String name; private Integer age; publ ...
- JAVA多线程编程——JAVA内存模型
一.何为“内存模型” 内存模型描述了程序中各个变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的底层细节,对象最终是存储在内存里面的,但是编译器 ...
- 关系代数演算So Easy
关系代数运算So Easy 关系代数是以关系为运算的一组高级运算的集合.由于定义为属性个数 相同的元组的集合,因此集合代数的操作就可以引入到关系代数中.关系代数也可以看做是一种抽象的查询语言,是对关系 ...
- 一个.java文件内只能写一个class吗
先给结论:当然不是!! 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致.一个文件中可以不含public类,如果只有一个非public类,此时可以跟文件名不同. 为 ...
- Memcached笔记之分布式算法
1.根据余数进行分散:离散度高,但是增加或者移除服务器的时候,缓存充足的代价非常大.添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而音像缓存的命中率. 2.Consistent ...
- C-基础:形参char *&p与char *p
char* &p:以引用传递的方式传指针char* p: 以值传递的方式传指针
- OO第三次电梯作业优化
目录 第三次电梯作业个人优化 前言 优化思路 一.调度器 二.电梯 第三次电梯作业个人优化 前言 由于个人能力有限,第二次电梯作业只能完成正确性设计,没能进行优化,也因此损失了强测分数,于是第三次电梯 ...
- 转 WebService两种发布协议--SOAP和REST的区别
转发文章 https://blog.csdn.net/zl834205311/article/details/62231545?ABstrategy=codes_snippets_optimize_v ...