1. 线程

  

from threading import Thread

def func(n):
print(n) if __name__ == '__main__':
t = Thread(target=func, args=(3,))
t.start()
print('主线程结束')

创建进程方法一

from threading import Thread

class MyThread(Thread):
def run(self):
print('XXX') if __name__ == '__main__':
t = MyThread()
t.start()
print('主线程结束')

创建进程方法二

2. 线程和进程的效率对比

  线程的效率非常高, 而且线程的开启不需要消耗资源

import time
from threading import Thread
from multiprocessing import Process def func(n):
num = 0
for n1 in range(n): # 做个运算, 消耗一下时间, 好比较线程与进程的效率
num += n1
print('num', num) if __name__ == '__main__':
t_s_t = time.time() # 线程运行起始时间
tlst = []
for i in range(10):
t = Thread(target=func, args=(10,))
t.start()
tlst.append(t)
[t.join() for t in tlst] # 迭代着join等待线程全部运行完毕
t_e_t = time.time() # 线程运行结束时间
t_dif_t = t_e_t - t_s_t # 计算线程的运行时间差 print('线程的结束时间', t_dif_t)
p_s_t = time.time()
plst = []
for i in range(10):
p = Process(target=func, args=(10,))
p.start()
plst.append(p)
[p.join() for p in plst] p_e_t = time.time()
p_dif_time = p_e_t - p_s_t
print('进程的结束时间', p_dif_time)
print('主线程结束', t_dif_t)

3. 线程之间数据共享

from threading import Thread

num = 100
def func():
global num
num = 0 if __name__ == '__main__':
t = Thread(target=func)
t.start()
print(num)
t.join()
print('主线程结束')

线程间数据共享

import time
import random
from threading import Thread n = 100
def func():
global n
x = n
x = x - 1
time.sleep(random.random())
n = x if __name__ == '__main__': for i in range(30):
t_lst = []
for i in range(10):
t = Thread(target=func)
t.start()
t_lst.append(t)
# [t.join() for t in t_lst]
print(n)

数据共享, 不安全

import time
from threading import Thread, Lock num = 100
def func(t_lock):
global num
t_lock.acquire()
mid = num
mid = mid - 1
time.sleep(0.0000001)
num = mid
t_lock.release() if __name__ == '__main__':
t_lock = Lock()
t_lst = []
for i in range(10):
t = Thread(target=func, args=(t_lock,))
t.start()
t_lst.append(t)
[t.join() for t in t_lst] print('主线程>>>', num)

共享数据加锁保障安全

4. 锁(同步锁/互斥锁)

  1. GIL (Global Interpreter Lock) 全局解释锁

  2. Lock  同步锁/互斥锁

  3. RLock  递归锁

  保证数据安全, 但是牺牲了效率, 同步执行锁内代码

  死锁现象: 当我们使用锁嵌套锁时, 多个线程异步执行的时候会出现线程之间相互争夺对方未释放的锁, 相互等待.   (互相抢到了对方需要的锁, 导致双方相互等待, 程序没法进行)

import time
from threading import Thread, Lock class MyThread(Thread): def __init__(self, lockA, lockB):
super().__init__()
self.lockA = lockA
self.lockB = lockB def run(self):
self.f1()
self.f2() def f1(self):
self.lockA.acquire()
print('我拿了A锁')
self.lockB.acquire()
print('我拿了B锁')
print('我是f1')
self.lockB.release()
self.lockA.release() def f2(self):
self.lockB.acquire()
time.sleep(1)
print('拿到了B锁')
self.lockA.acquire()
print('拿到了A锁')
print('我是f2')
self.lockA.release()
self.lockB.release() if __name__ == '__main__':
lockA = Lock()
lockB = Lock()
t1 = MyThread(lockA, lockB)
t1.start() t2 = MyThread(lockA, lockB)
t2.start() print('我是主线程')

死锁现象

  

  解决死锁: 递归锁 RLock   可以多次acquire, 通过一个计数器来记录被锁了多少次, 只有计数器为0的时候, 大家才能继续抢锁.

import time
from threading import Thread, Lock, RLock class MyThread(Thread): def __init__(self, lockA, lockB):
super().__init__()
self.lockA = lockA
self.lockB = lockB def run(self):
self.f1()
self.f2() def f1(self):
self.lockA.acquire()
print('我拿了A锁')
self.lockB.acquire()
print('我拿了B锁')
print('我是f1')
self.lockB.release()
self.lockA.release() def f2(self):
self.lockB.acquire()
time.sleep(1)
print('拿到了B锁')
self.lockA.acquire()
print('拿到了A锁')
print('我是f2')
self.lockA.release()
self.lockB.release() if __name__ == '__main__':
lockA = lockB = RLock()
t1 = MyThread(lockA, lockB)
t1.start() t2 = MyThread(lockA, lockB)
t2.start() print('我是主线程')

递归锁, 解决死锁

经典问题: 科学家吃面

import time
from threading import Thread,Lock, RLock def eat1(name, lockA, lockB):
lockA.acquire()
print('%s抢到了叉子' % name)
lockB.acquire()
print('%s抢到了面条' % name)
print('%s开始吃面啦~~' % name)
lockB.release()
lockA.release() def eat2(name, lockA, lockB):
lockB.acquire()
print('%s抢到了面条' % name)
time.sleep(1)
lockA.acquire()
print('%s抢到了叉子' % name)
print('%s开始吃面啦~~~' % name)
lockA.release()
lockB.release() if __name__ == '__main__':
lockA = lockB = RLock()
# lockA = Lock()
# lockB = Lock()
for name in ['alex', 'wu sir', 'boss king', 'taibai']:
t1 = Thread(target=eat1, args=(name, lockA, lockB))
t1.start()
t2 = Thread(target=eat2, args=(name, lockA, lockB))
t2.start()

死锁和递归锁解决死锁

5. 守护线程 

  主进程代码结束程序并没有结束,并且主进程还存在,进程等待其他的子进程执行结束以后,为子进程收尸,注意一个问题:主进程的代码运行结束守护进程跟着结束,

守护线程:

  主线程等待所有非守护线程的结束才结束,主线程的代码运行结束,还要等待非守护线程的执行完毕.这个过程中守护线程还存在

import time
from multiprocessing import Process
from threading import Thread def func(n):
time.sleep(5)
print(n) if __name__ == '__main__':
# 主线程等待的是子线程的任务全部执行完毕
t = Thread(target=func, args=('我是子线程',))
t.start()
# 主进程等待的是给子进程收尸, 回收资源,各种信息
# p = Process(target=func, args=('我是子进程',))
# p.start()
print('主线程结束')

主线程等待子线程的原因

import time
from multiprocessing import Process
from threading import Thread def func1(n):
time.sleep(5)
print(n) def func2(n):
time.sleep(2)
print(n) if __name__ == '__main__':
# p1 = Process(target=func1, args=('我是1号',))
# p1.daemon = True
# p1.start()
# p2 = Process(target=func2, args=('我是2号',))
# p2.start()
t1 = Thread(target=func1, args=('我是1号',))
# t1.daemon = True
t1.start()
t2 = Thread(target=func2, args=('我是2号',))
t2.daemon = True # 等待所有非守护线程结束
t2.start() print('主线程结束') # 守护进程在主进程运行代码结束时跟着结束, 不会跟着其他子进程执行

守护线程与守护进程差别

  

6. 信号量

  控制同时能够进入锁内去执行代码的线程数量(进程数量), 维护了一个计数器, 刚开始创建信号量的时候, 假如设置的是4个房间, 进入一次acquire就减1, 出来一个就+1, 如果计数器为0, name其他的任务等待, 这样其他的任务和正在执行的任务是一个同步的状态, 而进入acquire里面去执行的那4个任务是异步执行的.

# 和进程中信号量的按摩房一个道理, 相当于有多把锁
import time
from threading import Thread, Semaphore def func1(s):
s.acquire()
time.sleep(1)
print('你好啊')
s.release() if __name__ == '__main__':
s = Semaphore(4)
for i in range(10):
t = Thread(target=func1, args=(s,))
t.start()

超哥博客--Python之线程

Day036--Python--线程的更多相关文章

  1. python——线程与多线程进阶

    之前我们已经学会如何在代码块中创建新的线程去执行我们要同步执行的多个任务,但是线程的世界远不止如此.接下来,我们要介绍的是整个threading模块.threading基于Java的线程模型设计.锁( ...

  2. python——线程与多线程基础

    我们之前已经初步了解了进程.线程与协程的概念,现在就来看看python的线程.下面说的都是一个进程里的故事了,暂时忘记进程和协程,先来看一个进程中的线程和多线程.这篇博客将要讲一些单线程与多线程的基础 ...

  3. [python] 线程简介

    参考:http://www.cnblogs.com/aylin/p/5601969.html 我是搬运工,特别感谢张岩林老师! python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件 ...

  4. PYTHON线程知识再研习A

    前段时间看完LINUX的线程,同步,信息号之类的知识之后,再在理解PYTHON线程感觉又不一样了. 作一些测试吧. thread:模块提供了基本的线程和锁的支持 threading:提供了更高级别,功 ...

  5. Python 线程(threading) 进程(multiprocessing)

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  6. Python线程:线程的调度-守护线程

    Python线程:线程的调度-守护线程   守护线程与普通线程写法上基本么啥区别,调用线程对象的方法setDaemon(true),则可以将其设置为守护线程.在python中建议使用的是thread. ...

  7. python 线程(一)理论部分

    Python线程 进程有很多优点,它提供了多道编程,可以提高计算机CPU的利用率.既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的. 主要体现在一下几个方面: 进程只能在 ...

  8. python线程同步原语--源码阅读

    前面两篇文章,写了python线程同步原语的基本应用.下面这篇文章主要是通过阅读源码来了解这几个类的内部原理和是怎么协同一起工作来实现python多线程的. 相关文章链接:python同步原语--线程 ...

  9. Python学习——Python线程

    一.线程创建 #方法一:将要执行的方法作为参数传给Thread的构造方法 import threading import time def show(arg): time.sleep(2) print ...

  10. Python 线程和进程和协程总结

    Python 线程和进程和协程总结 线程和进程和协程 进程 进程是程序执行时的一个实例,是担当分配系统资源(CPU时间.内存等)的基本单位: 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其 ...

随机推荐

  1. Spring JDBC模版以及三种数据库连接池的使用

    jar包版本有点乱,直接忽略版本号,将就一下. 这里引了aop包是因为在spring3版本之后用模版对数据库库操作时会出现问题,但是不会报错,也没有提示. 所以这里直接引入,以及之后会用到的DBCP与 ...

  2. linux audit审计(8)--开启audit对系统性能的影响

    我们使用测试性能的工具,unixbench,它有一下几项测试项目: Execl Throughput 每秒钟执行 execl 系统调用的次数 Pipe Throughput 一秒钟内一个进程向一个管道 ...

  3. mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱

    ​ mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱 ​ 前言:使用 mybatis generator 生成表格对应的pojo.dao.mapper,以及对应的example的 ...

  4. springboot swagger2 泛型踩坑记

    最近使用一些工具需要和swagger打通,swagger的格式总是不对. 后来查了一下:哈哈. https://blog.csdn.net/hupingjin/article/details/8299 ...

  5. Mysql Router 的集群

    1. c:\mysql-router, c:\mysql-5.7.23, 这两个目录的bin都要加入path 2. c:\mysql-shell,在bin下,有一个 mysqlsh.exe, 双击,打 ...

  6. Delphi中Owner和Parent的区别

    Owner为创建者,Parent为容器 他们的类型不同,Owner为TComponent(元件),Parent为TWinControl(窗体控件) Parent属性是指构件的包容器,构件只能在此范围内 ...

  7. dataTable之自定义按钮实现全表 复制 打印 导出 重载

    //本文对常用表格插件datatable 的自定义按钮功能键进行详细解释//其中 15-78行是定义表单//16 18 19 三行定义自定义功能按钮 实现对全表的 复制 打印 导出(csv即excel ...

  8. 学习android开发之路(一)页面布局

    Android页面布局 1.Android页面布局一共分为6种: LinearLayout(线性布局).RelativeLayout(相对布局).TableLayout(表格布局).FrameLayo ...

  9. .net core 2.0 配置Session

    本文章为原创文章,转载请注明出处 配置Session 在Startup.cs文件的ConfigureServices方法中添加session services.AddSession(); 在Start ...

  10. Web.xml中Filter过滤器标签几个说明

    在研究liferay框架中看到Web.xml中加入了过滤器的标签,可以根据页面提交的URL地址进行过滤,发现有几个新标签没用过,下面就介绍以下几个过滤器的标签用法: <!-- 定义Filter ...