1.线程理论
什么是线程:线程是cpu的最小执行单位(实体),进程是操作系统的数据资源分配单位
2.线程的两种创建方式(重点)
查看线程的pid:使用os模块查看id,线程的id应该是相同的
3.多线程和多进程的效率对比:
IO密集型(遇到io切换提高代码效率)和计算密集型(切换降低代码效率):切换的时候需要保存状态和切换的时间
多线程用不了多核技术,遇到纯计算的时候,多线程回避多进程的运行时间高
import time
from threading import Thread
from multiprocessing import Process
def f1():
# time.sleep(1) #io密集型以后遇到的情况一遍是这样的
# a= 1
# a= a+1
# print('xxx')
pass
if __name__ == '__main__':
#查看一个20个多线程执行20个任务的执行时间
t_s_time = time.time()
t_list =[]
for i in range(20):
t = Thread(target=f1,)
t.start()
t_list.append(t)
[tt.join() for tt in t_list]
t_e_time = time.time()
t_dif_time = t_e_time - t_s_time
#查看一下20个进程执行同样的任务的执行时间
p_s_time = time.time()
p_list = []
for i in range(20):
p = Process(target=f1, )
p.start()
p_list.append(p)
[pp.join() for pp in t_list]
p_e_time = time.time()
p_dif_time = p_e_time - p_s_time
print('多线程的执行时间:', t_dif_time)
print('多进程的执行时间:', p_dif_time)
4.线程空间是不是隔离的:共享数据可以被更改,
import time
from threading import Thread
num =100
def f1(n):
time.sleep(3)
global num
num= 3
print('子线程的num',num)
if __name__ == '__main__':
t = Thread(target=f1,args=(1,))
t.start()
t.join()
print('主线程中的num',num)
#子线程的num 3
# 主线程中的num 3
5.守护线程
p.daemon =True 主进程的代码运行完毕,设置为守护进程的子进程会随之结束
6.锁(重点)
线程和进程的锁一样,都是牺牲了效率,保证了数据的安全
import time
from threading import Thread,Lock
num = 100
def f1(loc):
loc.acquire() #遇到锁,10个线程抢一个,一个进行更改数据,从并行状态更改成串行状态,牺牲的效率,保证了数据的安全
global num #global 只是声明变量,没有拿变量
# num -= 1
tmp = num
tmp -=1
time.sleep(0.2)
num = tmp
loc.release() #解锁,把上一个更改的数据更改完成之后进行解锁,解锁之后,剩余9个在重新抢这个锁在重新更改num值,
if __name__ == '__main__':
t_lock = Lock()
t_list = [] #把10个线程放到一个列表,保证线程结束,主要的等待线程的结束
for i in range(10):
t = Thread(target=f1,args=(t_lock,))
t.start()
t_list.append(t)
[tt.join() for tt in t_list]
print('主线程的num',num)
#主线程的num 90
死锁现象(重点):
两个锁进行了嵌套,一个锁包含了另一个锁
主要在数据运算\分析的时候,注意到锁跟锁嵌套的关系,容易出现死锁现象,解决这个现象问题,出现了递归锁
递归锁(重点) Rlock
import time
from threading import Thread,Lock,RLock
def f1(locA,locB):
print('xxxx')
time.sleep(0.1)
locA.acquire()
print('f1>>>1号抢到了A锁')
time.sleep(1)
locB.acquire()
print('f1>>>2号抢到了B锁')
locB.release()
locA.release()
def f2(locA,locB):
print('22222')
time.sleep(0.1)
locB.acquire()
print('f2>>>1号抢到了B锁')
time.sleep(1)
locA.acquire()
print('f2>>>2号抢到了A锁')
locB.release()
locA.release()
if __name__ == '__main__':
# locA = Lock()
# locB = Lock()
locA = locB = RLock() #递归锁,维护一个计数器,acquire一次加1,release一次减1,
t1 = Thread(target=f1, args=(locA, locB))
t2 = Thread(target=f2, args=(locA, locB))
t1.start()
t2.start()
# print(t1)
# print(t2)
递归锁,维护一个
GIL锁(重点)
解释器上添加的锁,互斥锁造成效率不高
计算密集型:多进程可以应用多核技术,因为每个进程里面都有解释器程序.
计算密集型的任务,由于python多线程,不能应用多核,所以效率不高,几个线程串行执行了.
io密集型的任务:多线程的任务比多进程更有优势,

1.线程理论
什么是线程:线程是cpu的最小执行单位(实体),进程是操作系统的数据资源分配单位
2.线程的两种创建方式(重点)
查看线程的pid:使用os模块查看id,线程的id应该是相同的
3.多线程和多进程的效率对比:
IO密集型(遇到io切换提高代码效率)和计算密集型(切换降低代码效率):切换的时候需要保存状态和切换的时间
多线程用不了多核技术,遇到纯计算的时候,多线程回避多进程的运行时间高
import time
from threading import Thread
from multiprocessing import Process
def f1():
# time.sleep(1) #io密集型以后遇到的情况一遍是这样的
# a= 1
# a= a+1
# print('xxx')
pass
if __name__ == '__main__':
#查看一个20个多线程执行20个任务的执行时间
t_s_time = time.time()
t_list =[]
for i in range(20):
t = Thread(target=f1,)
t.start()
t_list.append(t)
[tt.join() for tt in t_list]
t_e_time = time.time()
t_dif_time = t_e_time - t_s_time
#查看一下20个进程执行同样的任务的执行时间
p_s_time = time.time()
p_list = []
for i in range(20):
p = Process(target=f1, )
p.start()
p_list.append(p)
[pp.join() for pp in t_list]
p_e_time = time.time()
p_dif_time = p_e_time - p_s_time
print('多线程的执行时间:', t_dif_time)
print('多进程的执行时间:', p_dif_time)
4.线程空间是不是隔离的:共享数据可以被更改,
import time
from threading import Thread
num =100
def f1(n):
time.sleep(3)
global num
num= 3
print('子线程的num',num)
if __name__ == '__main__':
t = Thread(target=f1,args=(1,))
t.start()
t.join()
print('主线程中的num',num)
#子线程的num 3
# 主线程中的num 3
5.守护线程
p.daemon =True 主进程的代码运行完毕,设置为守护进程的子进程会随之结束
6.锁(重点)
线程和进程的锁一样,都是牺牲了效率,保证了数据的安全
import time
from threading import Thread,Lock
num = 100
def f1(loc):
loc.acquire() #遇到锁,10个线程抢一个,一个进行更改数据,从并行状态更改成串行状态,牺牲的效率,保证了数据的安全
global num #global 只是声明变量,没有拿变量
# num -= 1
tmp = num
tmp -=1
time.sleep(0.2)
num = tmp
loc.release() #解锁,把上一个更改的数据更改完成之后进行解锁,解锁之后,剩余9个在重新抢这个锁在重新更改num值,
if __name__ == '__main__':
t_lock = Lock()
t_list = [] #把10个线程放到一个列表,保证线程结束,主要的等待线程的结束
for i in range(10):
t = Thread(target=f1,args=(t_lock,))
t.start()
t_list.append(t)
[tt.join() for tt in t_list]
print('主线程的num',num)
#主线程的num 90
死锁现象(重点):
两个锁进行了嵌套,一个锁包含了另一个锁
主要在数据运算\分析的时候,注意到锁跟锁嵌套的关系,容易出现死锁现象,解决这个现象问题,出现了递归锁
递归锁(重点) Rlock
import time
from threading import Thread,Lock,RLock
def f1(locA,locB):
print('xxxx')
time.sleep(0.1)
locA.acquire()
print('f1>>>1号抢到了A锁')
time.sleep(1)
locB.acquire()
print('f1>>>2号抢到了B锁')
locB.release()
locA.release()
def f2(locA,locB):
print('22222')
time.sleep(0.1)
locB.acquire()
print('f2>>>1号抢到了B锁')
time.sleep(1)
locA.acquire()
print('f2>>>2号抢到了A锁')
locB.release()
locA.release()
if __name__ == '__main__':
# locA = Lock()
# locB = Lock()
locA = locB = RLock() #递归锁,维护一个计数器,acquire一次加1,release一次减1,
t1 = Thread(target=f1, args=(locA, locB))
t2 = Thread(target=f2, args=(locA, locB))
t1.start()
t2.start()
# print(t1)
# print(t2)
递归锁,维护一个
GIL锁(重点)
解释器上添加的锁,互斥锁造成效率不高
计算密集型:多进程可以应用多核技术,因为每个进程里面都有解释器程序.
计算密集型的任务,由于python多线程,不能应用多核,所以效率不高,几个线程串行执行了.
io密集型的任务:多线程的任务比多进程更有优势,

- 深入浅出 Java Concurrency (33): 线程池 part 6 线程池的实现及原理 (1)[转]
线程池数据结构与线程构造方法 由于已经看到了ThreadPoolExecutor的源码,因此很容易就看到了ThreadPoolExecutor线程池的数据结构.图1描述了这种数据结构. 图1 Thre ...
- day 33 线程池有关的
# cpu 的核心数# import os# print(os.cpu_count()) ## 爬虫的进程和线程的应用# 第一步 虚拟一个浏览器下载 在cmd 里输入 pip install requ ...
- day 33 线程锁
Python的GIL锁 - Python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度. 为什么有这把GIL锁? 答:Python语言的创始人在开发这门语言时, ...
- python基础(33):线程(一)
1. 线程概念的引入背景 1.1 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在 ...
- Java线程:线程的同步-同步方法
Java线程:线程的同步-同步方法 线程的同步是保证多线程安全访问竞争资源的一种手段. 线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问 ...
- Java线程:概念与原理
Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...
- Java线程:线程状态的转换
Java线程:线程状态的转换 一.线程状态 线程的状态转换是线程控制的基础.线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下: 1.新状态:线程对象已 ...
- java线程详解
Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...
- Java线程详解----借鉴
Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...
随机推荐
- Java实例---简单的个人管理系统
代码分析 FileOperate.java package com.ftl.testperson; import java.io.File ; import java.io.FileInputStre ...
- 安装office2016和激活。
严重声明:条件宽裕的同学可以购买正版.请大家多多支持正版. 自己手贱,原本在电脑win10系统上安装的正版office被误删了,联系了客服人员,但是自己的微软账号也忘记了.好想下载个正版的.自己在网上 ...
- 4 Dockerfile指令详解 && COPY 指令
COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置.比如: COPY package.json /usr/src/app/ ...
- December 07th 2016 Week 50th Wednesday
Life is a flower, and love is the honey of the flower. 人生是花儿,而爱情就是花的蜜. My life is not as beautiful a ...
- linux下常用命令:
常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir ...
- stderr: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
错误提示: (1). stderr: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer direc ...
- 字符串String及字符Char的相关方法
一.字符串: 1.访问String中的字符: string本身可看作一个Char数组. string s = "hello world"; ; i < s.Length; i ...
- codeforces 17C Balance(动态规划)
codeforces 17C Balance 题意 给定一个串,字符集{'a', 'b', 'c'},操作是:选定相邻的两个字符,把其中一个变成另一个.可以做0次或者多次,问最后可以生成多少种,使得任 ...
- BZOJ 3224 Tyvj 1728 普通平衡树模板
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 题目大意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以 ...
- curl 抓取页面信息
<?php // 1. 初始化 $ch = curl_init(); // 2. 设置选项,包括URL curl_setopt($ch, CURLOPT_URL, "www" ...