1,守护线程

import time
from threading import Thread
def func():
print('开始执行子线程')
time.sleep(3)
print('子线程执行完毕') t = Thread(target=func)
t.setDaemon(True) # 进程设置守护进程 是一个属性 daemon = True
t.start()
t2 = Thread(target=func)
t2.start()
t2.join() # 等待t2结束
# 守护线程 守护进程 都是等待主进程或者主线程中的代码 执行完毕
# t2 = Thread(target=func)
# t2.start() ---> 代码执行完毕
# 守护线程就结束了
# 主线程还没结束 等待t2继续执行
# t2执行完毕 主线程结束 # t2 = Thread(target=func)
# t2.start()
# t2.join() # 等待t2结束 执行完这句话代码才执行完毕
# t2线程执行完毕
# 主线程中没有代码了,守护线程结束

2,锁

import time
from threading import Thread
from threading import Lock
def func():
global n
time.sleep(2)
lock.acquire()
temp = n # 从进程中获取n
time.sleep(0.01)
n = temp-1 # 得到结果,再存储回进程
lock.release() n = 100
lock = Lock()
t_lst = []
for i in range(100):
t = Thread(target=func)
t.start()
t_lst.append(t)
[t.join() for t in t_lst]
print(n) # GIL 不是锁数据 而是锁线程
# 在多线程中 特殊情况 仍然要加锁 对数据

3,死锁

import time
from threading import RLock
from threading import Thread
m = kz = RLock() # def eat(name):
kz.acquire() # 拿到钥匙
print('%s拿到筷子了'%name)
m.acquire()
print('%s拿到菠萝蜜干了'%name)
print('%s吃菠萝蜜干'%name)
m.release()
kz.release() def eat2(name):
m.acquire() # 没有钥匙
print('%s拿到菠萝蜜干了' % name)
time.sleep(1)
kz.acquire()
print('%s拿到筷子了' % name)
print('%s吃菠萝蜜干' % name)
kz.release()
m.release()
Thread(target=eat,args=('兔子',)).start()
Thread(target=eat2,args=('rabbit',)).start()
Thread(target=eat,args=('大橘',)).start()
Thread(target=eat2,args=('Orange_Cat',)).start()
 
在不同的线程中 恰好要对这两个数据进行操作所以就出现了死锁。
4,信号量
 import time
import random
from threading import Thread
from threading import Semaphore
def func(n,sem):
sem.acquire()
print('thread -%s start'%n)
time.sleep(random.random())
print('thread -%s done' % n)
sem.release()
sem = Semaphore(5) # 一把锁有5把钥匙
for i in range(20):
Thread(target=func,args=(i,sem)).start()
# 信号量 和 线程池 有什么区别?
# 相同点 在信号量acquire之后,和线程池一样 同时在执行的只能有n个
# 不同点
# 开的线程数不一样 线程池来说 一共就只开5个线程 信号量有几个任务就开几个线程
# 对有信号量限制的程序来说 可以同时执行很多线程么?
# 实际上 信号量并不影响线程或者进程的并发,只是在加锁的阶段进行流量限制

5,事件

import time
import random
from threading import Event
from threading import Thread
def conn_mysql(): # 连接数据库
count = 1
while not e.is_set(): # 当事件的flag为False时才执行循环内的语句
if count>3:
raise TimeoutError
print('尝试连接第%s次'%count)
count += 1
e.wait(0.5) # 一直阻塞变成了只阻塞0.5
print('连接成功') # 收到check_conn函数内的set指令,让flag变为True跳出while循环,执行本句代码 def check_conn():
'''
检测数据库服务器的连接是否正常
'''
time.sleep(random.randint(1,2)) # 模拟连接检测的时间
e.set() # 告诉事件的标志数据库可以连接 e = Event()
check = Thread(target=check_conn)
check.start()
conn = Thread(target=conn_mysql)
conn.start()

6,条件

import threading
def run(n):
con.acquire()
con.wait() # 等着
print("run the thread: %s" % n)
con.release() if __name__ == '__main__':
con = threading.Condition() # 条件 = 锁 + wait的功能
for i in range(10):
t = threading.Thread(target=run, args=(i,))
t.start() while True:
inp = input('>>>')
if inp == 'q':
break
con.acquire() # condition中的锁 是递归锁
if inp == 'all':
con.notify_all()
else:
con.notify(int(inp)) # 传递信号 notify(1) --> 可以放行一个线程
con.release()

7,计时器

from threading import Timer

def hello():
print("hello, world")
while True: # 每隔一段时间要开启一个线程
t = Timer(10, hello) # 定时开启一个线程,执行一个任务
# 定时 : 多久之后 单位是s
# 要执行的任务 :函数名
t.start()

8,队列

import queue
pq = queue.PriorityQueue() # 值越小越优先,值相同就asc码小的先出
pq.put((1,'z'))
pq.put((1,'b'))
pq.put((15,'c'))
pq.put((2,'d'))
#
print(pq.get())
print(pq.get())

9,concurrent与线程池和回调函数

import time
import random
from concurrent import futures
def funcname(n):
print(n)
time.sleep(random.randint(1,3))
return n*'*'
def call(args):
print(args.result())
thread_pool = futures.ThreadPoolExecutor(5)#线程池
thread_pool.map(funcname,range(10)) # map,天生异步,接收可迭代对象的数据,不支持返回值
f_lst = []
for i in range(10):
f = thread_pool.submit(funcname,i) # submit 合并了创建线程对象和start的功能
f_lst.append(f)
thread_pool.shutdown() # close() join()
for f in f_lst: # 一定是按照顺序出结果
print(f.result()) #f.result()阻塞 等f执行完得到结果
# 回调函数 add_done_callback(回调函数的名字)
thread_pool.submit(funcname,1).add_done_callback(call)
												

python:线程进阶的更多相关文章

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

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

  2. Python爬虫进阶五之多线程的用法

    前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread ...

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

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

  4. [python] 线程简介

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

  5. PYTHON线程知识再研习A

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

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

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

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

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

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

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

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

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

  10. python最全学习资料:python基础进阶+人工智能+机器学习+神经网络(包括黑马程序员2017年12月python视频(百度云链接))

    首先用数据说话,看看资料大小,达到675G 承诺:真实资料.不加密,获取资料请加QQ:122317653 包含内容:1.python基础+进阶+应用项目实战 2.神经网络算法+python应用 3.人 ...

随机推荐

  1. PIE SDK算法的同步调用

    1.    算法功能简介 同步调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为. PIE SDK支持算法功能的执行,下面对算法的同步调用功能进行介绍. 2.    算法功能实现说明 2. ...

  2. 转帖 JS的基础语法2

    条件语句(if.switch). 循环语句(while.do…while. for … in).跳转语句(break,continue) 1.条件语句 Ø if语句 javascrip中的if语句 v ...

  3. 【3dsMax安装失败,如何卸载、安装3dMax 2010?】

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  4. (转)Python格式化字符 %s %d %f

    Python格式化字符 %s %d %f 原文:http://blog.csdn.net/huangfu77/article/details/54807835 格式 描述%% 百分号标记 #就是输出一 ...

  5. docker~环境变量到底怎么用

    docker已经用了两年多了,从开始的简单应用到现在的自动化部署,已经越来越感觉到它的威力,今天把Hitchhiker部署完成后,看到了它与.net core项目有个类似的地方,就是对于多环境部署的时 ...

  6. oracle 查询及删除表中重复数据

    create table test1( id number, name varchar2(20) ); ,'jack'); ,'jack'); ,'peter'); ,'red'); insert i ...

  7. Wireshark使用技巧

    Wireshark使用技巧 在分析网络时,包应该尽量的小,只要能定位问题即可. 1. 只抓包头,在wireshark中可以设置抓包大小. 如果使用tcpdump命令: [root@server_1 / ...

  8. 6、Modal

    1.首先Modal是一个内容窗格.通常用来做一个选择或编辑. 先来看一下 tabs.html 做了什么. /* --- tabs.html ----*/ <ion-navbar *navbar ...

  9. Docker 创建镜像、修改、上传镜像

    Docker 创建镜像.修改.上传镜像 –创建镜像有很多方法,用户可以从 Docker Hub 获取已有镜像并更新,也可以利用本地文件系统创建一个. 一.创建镜像 创建镜像有很多方法,用户可以从 Do ...

  10. 基于Ajax与用户认证系统的登录验证

    一.登录页面 from django.contrib import admin from django.urls import path from blog import views urlpatte ...