Python 之并发编程之线程上
一.线程概念
进程是资源分配的最小单位
线程是计算机中调度的最小单位
多线程(即多个控制线程)的概念是,在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源。(一个进程里面开多个线程(共享同一个进程里面的内存空间))
#线程的缘起
资源分配需要分配内存空间,分配cpu:
分配的内存空间存放着临时要处理的数据等,比如要执行的代码,数据
而这些内存空间是有限的,不能无限分配
目前配置高的主机,5万个并发已是上限.线程概念应用而生.
#线程的特点
线程是比较轻量级,能干更多的活,一个进程中的所有线程资源是共享的.
一个进程至少有一个线程在工作
### 线程的缺陷
#线程可以并发,但是不能并行(即可以1个cpu执行,不能多个cpu一起执行)
#原因:
python是解释型语言,执行一句编译一句,而不是一次性全部编译成功,不能提前规划,都是临时调度
容易造成不同的cpu却反复执行同一个程序.所以加了一把锁叫GIL
全局解释器锁(Cpython解释器特有) GIL锁:同一时间一个线程只能被一个cpu执行
#想要并行的解决办法:
(1)用多进程间接实现线程的并发
(2)换一个Pypy,Jpython解释器
#程序分为计算密集型和io密集型
对于计算密集型程序会过度依赖cpu,但网页,爬虫,OA办公,这种io密集型的程序里,python绰绰有余
### 线程相关函数
线程.is_alive() 检测线程是否仍然存在
线程.setName() 设置线程名字
线程.getName() 获取线程名字
currentThread().ident 查看线程id号
enumerate() 返回目前正在运行的线程列表
activeCount() 返回目前正在运行的线程数量
pyhton上是一个任务首先在一个进程上执行,在多个线程内循环执行,然后换到另外一个进程再继续执行,再循环线程,不停的切换,不能进行并行,可以的是进程并发操作,就是这个任务先暂停一下,先换成另外一个任务进程执行。
因为python中有一个GIL锁。
而java上的线程是,多个任务在多个线程上进行执行。不需要不停地进行更换,线程。
二.线程的基本语法
在下面开始之前都需要导入:
from threading import Thread
from multiprocessing import Process
import os, time, random
1.一个进程可以多个线程
def func(num):
time.sleep(random.uniform(0.1, 1))
print("子线程", num, os.getpid())
for i in range(10):
t = Thread(target=func, args=(i,))
t.start()

2.并发多线程和多进程的速度对比? 多线程更快
def func(i):
#time.sleep(random.uniform(0.1,1))
print("子线程",i,os.getpid())
if __name__ == "__main__":
# 1. 计算多线程的执行速度
startime = time.perf_counter()
lst= []
for i in range(1000):
t = Thread(target=func,args=(i,))
t.start()
lst.append(t)
for i in lst:
i.join()
print("程序执行结束")
endtime = time.perf_counter()
print(endtime-startime) #0.2554951
# 2.计算多进程的执行速度
startime = time.perf_counter()
lst = []
for i in range(1000):
p = Process(target=func,args=(i,))
p.start()
lst.append(p)
for i in lst:
i.join()
print("程序执行结束")
endtime = time.perf_counter()
print(endtime-startime) #66.66021479999999
3.多线程共享同一份进程资源
最后得出的数值为0,说明资源共享。
例:
num = 100
lst = []
def func():
global num
num -= 1
for i in range(100):
t = Thread(target=func)
t.start()
lst.append(t)
for i in lst:
i.join()
print(num)
4.线程相关函数
线程.is_alive() 检测线程是否仍然存在
线程.setName() 设置线程名字
线程.getName() 获取线程名字
例:
def func():
#time.sleep(0.1)
pass
t = Thread(target=func)
t.start()
print(t.is_alive()) # False
print(t.getName()) #Thread-1
t.setName("hsz")
print(t.getName()) # hsz
time.sleep(2)
print(t.is_alive()) #False,线程已经结束了所有False
1.currentThread().ident 查看线程id
2.enumerate() 返回目前正在运行的线程列表
3.activeCount() 返回目前正在运行的线程数量
# 1.currentThread().ident 查看线程id号
from threading import current_thread
def func():
print("子线程:",current_thread().ident)
t = Thread(target=func)
t.start()
print("主线程:",current_thread().ident)
# 2.enumerate() 返回目前正在运行的线程列表
from threading import current_thread
from threading import enumerate
def func():
print("子线程:", current_thread().ident)
time.sleep(0.5)
for i in range(10):
t = Thread(target=func)
t.start()
print(len(enumerate()))
time.sleep(3)
# 10个子线程 + 1个主线程 = 11个正在运行的线程
print(enumerate())
print(len(enumerate()))
# 3.activeCount() 返回目前正在运行的线程数量
from threading import current_thread
from threading import activeCount
def func():
print("子线程:", current_thread().ident)
time.sleep(0.5)
for i in range(10):
t = Thread(target=func)
t.start()
print(activeCount())
三.守护线程
守护线程 :等待所有线程执行结束之后,在自动结束,守护所有线程.
例:
from threading import Thread
import time
def func1():
while True:
time.sleep(0.5)
print("我是守护线程")
def func2():
print("func2 -> start")
time.sleep(3)
print("func2 -> end")
t1 = Thread(target=func1)
# setDaemon 讲t1线程对象变成守护线程
t1.setDaemon(True)
t1.start()
t2 = Thread(target=func2)
t2.start()
time.sleep(5)
print("主线程执行结束")

Python 之并发编程之线程上的更多相关文章
- python 之 并发编程(线程Event、协程)
9.14 线程Event connect线程执行到event.wait()时开始等待,直到check线程执行event.set()后立即继续线程connect from threading impor ...
- Python 之并发编程之线程中
四.线程锁lock(线程的数据安全) 在数据量较大的时候,线程中的数据会被并发,所有数据会不同步,以至于数据会异常. 下面还介绍了两种的上锁方法. 例: from threading import T ...
- Python 之并发编程之线程下
七.线程局部变量 多线程之间使用threading.local 对象用来存储数据,而其他线程不可见 实现多线程之间的数据隔离 本质上就是不同的线程使用这个对象时,为其创建一个只属于当前线程的字典 拿空 ...
- Python 之并发编程之进程上(基本概念、并行并发、cpu调度、阻塞 )
一: 进程的概念:(Process) 进程就是正在运行的程序,它是操作系统中,资源分配的最小单位. 资源分配:分配的是cpu和内存等物理资源 进程号是进程的唯一标识 同一个程序执行两次之后是两个进程 ...
- python 之 并发编程(线程理论,开启线程的两种方式,进程与线程的区别,线程对象的其他方法)
9.9 线程理论 1.什么是线程 线程指的是一条流水线的工作过程 进程根本就不是一个执行单位,进程其实是一个资源单位,一个进程内自带一个线程,线程才是执行单位 2.进程VS线程 同一进程内的线程们共享 ...
- 《转载》Python并发编程之线程池/进程池--concurrent.futures模块
本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...
- python并发编程之线程/协程
python并发编程之线程/协程 part 4: 异步阻塞例子与生产者消费者模型 同步阻塞 调用函数必须等待结果\cpu没工作input sleep recv accept connect get 同 ...
- Python 3 并发编程多进程之队列(推荐使用)
Python 3 并发编程多进程之队列(推荐使用) 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 可以往 ...
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
随机推荐
- vue中的回到顶部
<template> <div class="main"> <div class="content">灰色部分是内容部分&l ...
- Oracle expdp 多表导出处理
一个项目中需要在oracle数据库某个用户下导出1000多个表,导入到测试库做数据分析测试.很少遇到需要导出这么多表的情况,通常都是按schema导出,或者整库导出.考虑到expdp中include参 ...
- 微信小程序--缓存,支持过期时间的二次开发封装
简介 微信小程序提供了缓存的api,包括同步和异步两种,具体api不多说明,可自行查看官方文档 现在微信小程序缓存api存在一个问题就是没有设定过期时间,下面给大家介绍一下对小程序缓存的二次封装,使其 ...
- Go性能调优
文章引用自 Go性能调优 在计算机性能调试领域里,profiling 是指对应用程序的画像,画像就是应用程序使用 CPU 和内存的情况. Go语言是一个对性能特别看重的语言,因此语言中自带了 pr ...
- ubuntu的dpkg命令安装和卸载软件
实际使用中,可以先到网上下载deb文件,然后用dpkg命令来安装. sudo dpkg -l | grep 360 #查看包含360的软件sudo dpkg -i browser360-cn-stab ...
- 外键约束:foreign key
*外键 foreign key* 1.概念:如果一个实体的(student)的某个字段,指向(引用)另个实体(class)的主键 (class:class_id),就称为student实体的class ...
- 动态链接--运行时加载dlopen
前面我们在编译可执行文件时,如果可执行文件要依赖某个so.必须要通过-L指定so路径,并且-l指定so名字. 而且在可执行文件运行时,要先加载so的load部分到进程地址空间. 有一种方式可以在编译时 ...
- 浅谈分治 —— 洛谷P1228 地毯填补问题 题解
如果想看原题网址的话请点击这里:地毯填补问题 原题: 题目描述 相传在一个古老的阿拉伯国家里,有一座宫殿.宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子 ...
- composer install报错intervention/image 2.4.x-dev requires ext-fileinfo * -> the requested PHP extension fileinfo is missing from your system.
(1)问题:intervention/image 2.4.x-dev requires ext-fileinfo * -> the requested PHP extension fileinf ...
- CCF 试题编号: 201909-4 试题名称: 推荐系统
这题是stl的综合应用,map要想快,直接上unordered_map,这样查询接近O(1),是不是很嗨皮. 思路其实还是很简单的,type+id做个Hash,由于set.insert的第一个返回值是 ...