什么是线程

进程:资源分配单位

线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程

线程的两种创建方式:

from multiprocessing import Process
def f1(n):
print(n,'号线程') if __name__ == '__main__':
t1 = Thread(target=f1,args=(1,))
t1.start()
print('主线程')

from threading import Thread
class MyThread(Thread):
def __init__(self,name):
super().__init__()
self.name = name def run(self):
print('hello:' + self.name) if __name__ == '__main__': t = MyThread('haha')
t.start()
print('主线程结束')

线程的创建和销毁,相对于进程来说开销特别小

线程之间资源共享,共享的是同一个进程中的资源,  资源共享就涉及到数据安全问题,加锁来解决

线程锁

From threading import Thread,Lock

def f1: 

  Loc.acquire()

  代码

  Loc.release()

main

  Loc = Lock()

  T = thread(target=f1,args=(loc,)

from multiprocessing import Queue
import queue
import time
from threading import Lock,Thread num = 100
def f1(loc):
loc.acquire()
global num
tmp = num
tmp -= 1
time.sleep(0.001)
num = tmp
loc.release() if __name__ == '__main__': t_loc = Lock()
t_list = []
for i in range(10):
t = Thread(target=f1,args=(t_loc,))
t.start()
t_list.append(t)
[tt.join() for tt in t_list]
print('主线的num',num)

锁:牺牲了效率,保证了数据安

死锁现象(天长地久,永不分离):

出现在锁嵌套的时候,双方互相抢对方已经拿到的锁,导致双方互相等待,这就是死锁现象

import time
from threading import Thread,Lock,RLock def f1(locA,locB):
locA.acquire()
print('f1>>1号抢到了A锁')
time.sleep(1)
locB.acquire()
print('f1>>1号抢到了B锁')
locB.release() locA.release()
def f2(locA,locB):
locB.acquire() print('f2>>2号抢到了B锁') locA.acquire()
time.sleep(1)
print('f2>>2号抢到了A锁')
locA.release() locB.release()
if __name__ == '__main__':
locA = Lock()
locB = Lock()
t1 = Thread(target=f1,args=(locA,locB))
t2 = Thread(target=f2,args=(locA,locB))
t1.start()
t2.start()

递归锁:

解决死锁现象

Rlock  首先本身就是个互斥锁,维护了一个计数器,每次acquire就+1,release就-1,当计数器为0的时候,大家才能抢这个锁

import time
from threading import Thread, Lock, RLock def f1(locA, locB):
locA.acquire()
print('f1>>1号抢到了A锁')
time.sleep(1)
locB.acquire()
print('f1>>1号抢到了B锁')
locB.release()
locA.release() def f2(locA, locB):
locB.acquire()
print('f2>>2号抢到了B锁')
locA.acquire()
time.sleep(1)
print('f2>>2号抢到了A锁')
locA.release()
locB.release() if __name__ == '__main__': locA = locB = RLock()
t1 = Thread(target=f1, args=(locA, locB))
t2 = Thread(target=f2, args=(locA, locB))
t1.start()
t2.start()

守护线程:

守护线程:等待所有非守护线程的结束才结束

守护进程:主进程代码运行结束,守护进程就随之结束

import time
from threading import Thread
from multiprocessing import Process def f1():
time.sleep(2)
print('1号线程')
def f2():
time.sleep(3)
print('2号线程') if __name__ == '__main__':
t1 = Thread(target=f1,)
t2 = Thread(target=f2,)
t2.daemon = True
t1.start()
t2.start()
print('主线程结束')

GIL锁 :

  cpython解释器上的一把互斥锁,当线程需要进入cpu做运算时必须一个一个经过GIL锁

线程的事件,信号量 与进程的事件,信号量 用法相同.

python并发编程-线程和锁的更多相关文章

  1. Python并发编程-线程同步(线程安全)

    Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...

  2. python 并发编程 多进程 互斥锁 目录

    python 并发编程 多进程 互斥锁 模拟抢票 互斥锁与join区别

  3. Python并发编程-线程

    Python作为一种解释型语言,由于使用了全局解释锁(GIL)的原因,其代码不能同时在多核CPU上并发的运行.这也导致在Python中使用多线程编程并不能实现并发,我们得使用其他的方法在Python中 ...

  4. 15.python并发编程(线程--进程--协程)

    一.进程:1.定义:进程最小的资源单位,本质就是一个程序在一个数据集上的一次动态执行(运行)的过程2.组成:进程一般由程序,数据集,进程控制三部分组成:(1)程序:用来描述进程要完成哪些功能以及如何完 ...

  5. Python并发编程-线程锁

    互斥锁-Lock #多线程中虽然有GIL,但是还是有可能产生数据不安全,故还需加锁 from threading import Lock, Thread #互斥锁 import time def ea ...

  6. 53_并发编程-线程-GIL锁

    一.GIL - 全局解释器锁   有了GIL的存在,同一时刻同一进程中只有一个线程被执行:由于线程不能使用cpu多核,可以开多个进程实现线程的并发,因为每个进程都会含有一个线程,每个进程都有自己的GI ...

  7. python 并发编程 多线程 互斥锁

    互斥锁 并行变成串行,牺牲效率 保证数据安全,实现局部串行 保护不同的数据,应该加不同的锁 现在一个进程 可以有多个线程 所有线程都共享进程的地址空间 实现数据共享 共享带来问题就会出现竞争 竞争就会 ...

  8. python网络编程--线程递归锁RLock

    一:死锁 所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...

  9. python 并发编程 多进程 互斥锁与join区别

    互斥锁与join 互斥锁和join都可以把并发变成串行 以下代码是用join实现串行 from multiprocessing import Process import time import js ...

随机推荐

  1. 【ElasticSearch】:Mapping相关

    Mapping 类似数据库中的表结构定义,主要作用如下: 定义Index下的字段名(Field Name). 定义字段类型,例如数值型.字符串型.布尔型等. 定义倒排索引相关配置,比如是否索引.记录p ...

  2. 详解使用flask_paginate进行分页

    分页技术好处: 1.分页技术是把数据全部查询出来,然后再进行分页 2.分页技术可以,降低带宽使用,提高访问速度 使用flask_paginate进行分页 1.要使用flask_paginate,首先安 ...

  3. 剑指offer十五之反转链表

    一.题目 输入一个链表,反转链表后,输出链表的所有元素. 二.思路 详细分析见代码注释 三.代码 public class Solution {     public ListNode Reverse ...

  4. Storm中的定时任务

    1.全局定时器 import java.util.Map; import backtype.storm.Config; import backtype.storm.Constants; import ...

  5. 源码分析篇 - Android绘制流程(二)measure、layout、draw流程

    performTraversals方法会经过measure.layout和draw三个流程才能将一帧View需要显示的内容绘制到屏幕上,用最简化的方式看ViewRootImpl.performTrav ...

  6. Android四大组件之一 -- Service详解

    相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序 ...

  7. Disruptor入门

    一.什么是 Disruptor Disruptor是一个高性能的异步处理框架,或者可以认为是最快的消息框架(轻量的JMS),也可以认为是一个观察者模式实现,或者事件-监听模式的实现,直接称disrup ...

  8. docker(二)部署docker容器虚拟化平台

    yum安装方法参考:https://www.cnblogs.com/yufeng218/p/8370670.html https://www.cnblogs.com/straycats/p/84112 ...

  9. springmvc json 406

    spring 4.0 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="ht ...

  10. Java设计模式学习记录-适配器模式

    前言 之前已经将五个创建型设计模式介绍完了,从这一篇开始介绍结构型设计模式,适配器模式就是结构型模式的一种,适配器要实现的效果是把“源”过渡到“目标”. 适配器模式 在开发过程中,使用一个已经存在的类 ...