标签:串行 tpi bre cti isa while 为什么 字节码 打开
#
# [<_mainthread started>, ]
# 2
# 主进程/主线程
# Thread-1
# join 方法
# from threading import Thread
# import time
# def func():
# time.sleep(2)
# print(‘睡觉‘)
#
# if __name__ == ‘__main__‘:
# t = Thread(target=func)
# t.start()
# t.join() # 等待子线程先执行,子线程结束后执行主进程
# print("主线程")
# print(t.is_alive())
# 结果:
# 睡觉
# 主线程
# False
# 守护线程
# 无论是进程还是线程,都遵循:守护xx会等待主xx运行完毕后被销毁.需要强调的是:运行完毕并非终止运行
# 1.对主进程来说,运行完毕指的是主进程代码运行完毕
# 2.对主线程来说,运行完毕指的是主线程内所有的进程内所有非守护全部运行完毕,主进程才算运行完毕
# 具体解释:
# 1.主进程在其代码结束后就已经算运行完毕(守护进程在此时就被回收),然后主进程会一直非守护的子进程都
#运行完毕后回收子进程的资源(否者会产生僵死进程),才会结束.
# 2.主线程在其它非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收).因为主线程
#的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束
# from threading import Thread
# import time
# def func1():
# time.sleep(3)
# print("睡觉")
# def func2():
# time.sleep(2)
# print("吃饭")
# if __name__ == ‘__main__‘:
# t = Thread(target=func1)
# t.daemon = True # 守护线程必须在start之前
# t.start()
# time.sleep(3)
# t1 = Thread(target=func2) # 普通线程
# t1.start()
# print("主线程")
# print(t.is_alive())
# print(t1.is_alive())
# 守护线程是随着主线程执行结束而结束
# 守护线程不是根据主线程的代码执行结束而结束
# 主线程要等普通线程结束才结束
# 所以,一般把不重要的事情设置为守护线程
#结果:
# 睡觉
# 主线程
# False
# True
# 吃饭
# 验证守护进程
# from multiprocessing import Process
# import time
# def func1():
# time.sleep(2)
# print("睡觉")
#
# def func2():
# time.sleep(1)
# print("吃饭")
# if __name__ == ‘__main__‘:
# p = Process(target=func1)
# p.daemon = True # 守护进程
# p.start()
# p1 = Process(target=func2)
# p1.start()
# print(‘主进程‘)
# print(p.is_alive())
# 守护进程是随着主进程代码块结束而结束.
# 锁
#锁和GIL
#同步锁
# 在多用户抢占资源的情况下
# from threading import Thread
# import time,os
#
# def func():
# global n # 定义全局变量
# temp = n
# time.sleep(0.1)
# n = temp - 1
# #print(n)
# if __name__ == ‘__main__‘:
# n = 100
# lst = []
# for i in range(100):
# t = Thread(target=func)
# lst.append(t)
# t.start()
# [t.join() for t in lst]
# print(n)
# 结果为 99
# 同步锁的引用:
# from threading import Thread,Lock
# import os,time
# def func(l):
# global n
# l.acquire() # 上锁
# temp = n
# time.sleep(0.1)
# n = temp - 1
# l.release()
#
# if __name__ == ‘__main__‘:
# l = Lock()
# n = 100
# lst = []
# for i in range(100):
# t = Thread(target=func,args=(l,))
# lst.append(t)
# t.start()
# [t.join() for t in lst]
# print(n) # 结果是0 由原来的并发执行变成串行,牺牲了执行效率保证了数据安全
# 互斥锁和join的区别
# 不加锁:并发执行,速度快,数据不安全
# from threading import Thread,Lock,current_thread
# import time,os
#
# def func():
# global n
# print(‘%s is running‘ %current_thread().getName())
# temp = n
# time.sleep(0.5)
# n = temp -1
#
# if __name__ == ‘__main__‘:
# n = 100
# lst = []
# start = time.time()
# for i in range(100):
# t = Thread(target=func)
# lst.append(t)
# t.start()
# [t.join() for t in lst]
# print(‘主:%s n:%s‘ %(time.time() - start,n))
# 结果:
# Thread-1 is running
# Thread-2 is running
#.......
# Thread-99 is running
# Thread-100 is running
# 主:0.5100293159484863 n:99
#
# 不加锁:未加锁部分并发执行,加锁部分串行,速度慢,数据安全
# from threading import current_thread,Thread,Lock
# import os,time
#
# def func():
# #未加锁代码并发执行
# time.sleep(4)
# print("%s start to run" %current_thread().getName())
# global n
# # 加锁的代码串行运行
# lock.acquire()
# temp = n
# time.sleep(0.5)
# n = temp -1
# lock.release
#
# if __name__ == ‘__main__‘:
# n = 100
# lock = Lock()
# lst = []
# start = time.time()
# for i in range(100):
# t = Thread(target=func)
# lst.append(t)
# t.start()
# for t in lst:
# t.join()
# print("主:%s n:%s" %(time.time() - start,n))
#
# 死锁和递归锁
# 死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象
#诺无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些
#在相互等待的进程称为死锁进程
# 死锁代码:
# from threading import Lock
# import time
# muteAx = Lock()
# muteAx.acquire()
# muteAx.acquire()
# print(123)
# muteAx.release()
# muteAx.release()
# # 程序死锁等待
#解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供
#了可以重入锁RLock
# 这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,conger
#使得资源可以多次release.直到一个线程所有的acquire都被release,其他的线程才能获得资源
# 改进版
# from threading import RLock
# import time
# muteAx = RLock()
# muteAx.acquire()
# muteAx.acquire()
# print(123)
# muteAx.release()
# muteAx.release()
# 结果:123
# 典型问题,科学家吃面问题
# from threading import Thread ,Lock
# import time
# noodle_lock = Lock()
# fork_lock = Lock()
#
# def eat1(name):
# noodle_lock.acquire()
# print("%s抢到面条" %name)
# fork_lock.acquire()
# print(‘%s抢到叉子‘%name)
# print(‘%s吃面‘%name)
# fork_lock.release()
# noodle_lock.release()
#
# def eat2(name):
# fork_lock.acquire()
# print(‘%s抢到叉子‘%name)
# time.sleep(1)
# noodle_lock.acquire()
# print("%s抢到面条"%name)
# print(‘%s吃面‘%name)
# noodle_lock.release()
# fork_lock.release()
#
# for name in [‘哪吒‘,‘egon‘,‘yuan‘]:
# t1 = Thread(target=eat1,args=(name,))
# t2 = Thread(target=eat2,args=(name,))
# t1.start()
# t2.start()
# 结果:程序卡住
# 解决递归死锁问题
# from threading import Thread,RLock
# import time
# fork_lock = noodle_lock = RLock()
#
# def eat1(name):
# noodle_lock.acquire()
# print("%s抢到面条了"%name)
# fork_lock.acquire()
# print("%s抢到了叉子"%name)
# print(‘%s吃面‘%name)
# fork_lock.release() # 还叉子
# noodle_lock.release() # 还面
#
# def eat2(name):
# fork_lock.acquire()
# print("%s抢到叉子"%name)
# time.sleep(1)
# noodle_lock.acquire()
# print(‘%s抢到面条‘%name)
# print(‘%s吃面‘%name)
#
# for name in [‘哪吒‘,‘alex‘,‘太白‘]:
# t1 = Thread(target=eat1,args=(name,))
#
# t2 = Thread(target=eat2,args=(name,))
# t1.start()
# t2.start()
# 信号量
#同进程的一样
#Semaphore管理一个内置的计数器
#每当调用acquire()时内置计算器-1
#调用release()时内置计数器+1
#计数器不能小于0,当计数器为0时,acquire()将阻塞线程直到其他线程调用release()
#实例:同时只有5个线程可以获得Semaphore即可以限制最大连接数为5个
# from threading import Thread,Semaphore
# import threading,time
#
# def func():
# sm.acquire()
# print(‘%s get sm‘%threading.current_thread().getName())
# time.sleep(3)
# sm.release()
#
# if __name__ == ‘__main__‘:
# sm = Semaphore(5)
# for i in range(10):
# t = Thread(target=func)
# t.start()
# 事件
#和进程的一样
#线程的一个关键性是每个线程都是独立运行且状态不可预测.如果程序中有其它线程需通过判断某个线程
#的状态来确定自己下一步操作,这时线程同步问题就会变的非常棘手.为了解决这些问题,我们需要
#使用threading库中的Event对象.对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的
#发生.在初始情况下Event对象中的信号标志被设置为假.如果有线程等待一个Event对象,而这个Event
#Event对象的标志为假,那么这个线程会被一直阻塞直到标志为真.一个线程如果将一个Event对象的
#信号标志设置为真,它将唤醒所有等待这个Event对象的线程.如果一个线程等待一个已经被设置为真
#的Event对象,那么它将忽略这个事件,继续执行
# event.isSet(): 返回Event的状态值
# event.wait():如果event.isSet()==False将阻塞线程
# event.set():设置event的状态值为True,所有阻塞池的线程激活进入就绪状态,等待操作系统调度
#
# event.clear():恢复event的状态值为False
#
#例如 有很多个工作线程尝试连接MySQL,我们想要在连接前确保MySQL服务正常才让那些工作线程去
#连接MySQL服务器,如果连接不成功,都会尝试重新连接.那么我们就可以采用htreading.Event机制
#来协调各个工作线程的连接操作
# from threading import Thread,Event
# import threading,time,random
#
# def conn_mysql(): # 连接服务器
# count = 1
# while not event.is_set():
# if count > 3:
# raise TimeoutError(‘链接超时‘)
# print(‘第%s次尝试链接‘%(threading.current_thread().getName(),count))
# event.wait(0.5)
# count += 1
# print("链接成功"%threading.current_thread().getName())
#
#
# def check_mysql():
# print("\033[32m[%s]正在检查mysql\033[0m"%threading.current_thread().getName())
# time.sleep(random.randint(1,3))
# event.set()
#
#
# if __name__ == ‘__main__‘:
# event = Event()
# conn1 = Thread(target=conn_mysql)
# conn2 = Thread(target=conn_mysql)
# check = Thread(target=check_mysql())
# conn1.start()
# conn2.start()
# check.start()
#
#
# 条件
#使得线程等待,只有满足条件时,才释放n个线程
#Python提供的Condition对象提供了对复杂线程同步问题的支持Condition被称为条件变量,除了
#提供与Lock类似的acquire和release方法外,还提供了wait和notify方法.线程首先acquire一个条件变量
#然后判断一些条件.如果条件不满足则wait,如果条件满足,进行一些处理改变条件后,通过notify方法通知
# 其他线程,其它处于wait状态的线程接到通知后会重新判断条件.不断的重复这一过程,从而解决复杂的问题
# from threading import Thread,Condition
#
# def run(n):
# con.acquire()
# con.wait()
# print(‘run the thread:%s‘%n)
# con.release()
#
# if __name__ == ‘__main__‘:
# con = Condition()
# for i in range(10):
# t = Thread(target=run,args=(i,))
# t.start()
# while 1:
# inp = input(">>>>")
# if inp.upper() == "Q":
# break
# con.acquire()
# con.notify(int(inp))
# con.release()
# print("****")
# 定时器
# 定时器,指定n秒后执行某个操作
# from threading import Timer
# Timer(time,func)
# time:睡眠的时间,以秒为单位
# func:睡眠时间之后,需要执行的任务
from threading import Timer
def hello():
print(‘hello,world‘)
t = Timer(5,hello) # 警示定时5秒执行函数hello
t.start()
Python线程
标签:串行 tpi bre cti isa while 为什么 字节码 打开
原文地址:https://www.cnblogs.com/caodneg7/p/9535544.html