import os
import time
from threading import Thread,Lock
import threading
from multiprocessing import Process
lock=Lock()
def work1(id):
print(id)
lock.acquire() #进行上锁
time.sleep(6)
lock.release() #释放锁,
class Work2():
def __init__(self,name):
self.name=name
self.run()
def run(self):
print("in work2.....")
time.sleep(6)
class Work3(Thread):
def __init__(self,name):
super().__init__()
self.name=name
self.run()
def run(self):
print("in work3 ......")
time.sleep(5)
if __name__ == '__main__':
th1=Thread(target=work1,args=(2,))
th2=Thread(target=Work2,args=("xiaohong",))
th3=Work3("xiaoming")
th1.setDaemon(True) # 必须在th1.start()之前设置
th1.start()
th2.start()
th3.start()
print(th1.is_alive())
print(th1.getName())
print(th1.setName("th1"))
print(threading.enumerate())
print(threading.current_thread())
print(threading.active_count())
print(os.getpid())
print(os.cpu_count()) #打印cpu核数
#
# Thread实例对象的方法
# # isAlive(): 返回线程是否活动的。
# # getName(): 返回线程名。
# # setName(): 设置线程名。
# # setDaemon: 守护线程
# threading模块提供的一些方法:
# # threading.currentThread(): 返回当前的线程变量。
# # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
# # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
#运行结果
# in work3 ......
# 2
# in work2.....
# in work3 ......
# True
# Thread-1
# None
# [<_MainThread(MainThread, started 4321252224)>, <Thread(th1, started 123145381146624)>, <Work3(xiaoming, started 123145391656960)>, <Thread(Thread-2, started 123145386401792)>]
# <_MainThread(MainThread, started 4321252224)>
# 4
#守护线程
#1.对主进程来说,运行完毕指的是主进程代码运行完毕
#2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
#GIL
#首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。
# 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,
# INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。
# 像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,
# 也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL
# 多线程用于IO密集型,如socket,爬虫,web
# 多进程用于计算密集型,如金融分析
#锁:
# 加锁和不加锁,加锁执行速度慢,但是数据安全;不加锁执行速度快,但是数据不安全
# 死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
# 它们都将无法推进下去此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁
from threading import Thread,Lock
import time
mutexA=Lock()
mutexB=Lock()
class MyThread(Thread):
def run(self):
self.func1()
self.func2()
def func1(self):
mutexA.acquire()
print('\033[41m%s 拿到A锁\033[0m' %self.name)
mutexB.acquire()
print('\033[42m%s 拿到B锁\033[0m' %self.name)
mutexB.release()
mutexA.release()
def func2(self):
mutexB.acquire()
print('\033[45m%s 拿到B锁\033[0m' %self.name)
time.sleep(2)
mutexA.acquire()
print('\033[44m%s 拿到A锁\033[0m' %self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(10):
t=MyThread()
t.start()
# 解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
#
# 这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。
# 直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:
# mutexA=mutexB=threading.RLock() #一个线程拿到锁,counter加1,该线程内又碰到加锁的情况,则counter继续加1,
# 这期间所有其他线程都只能等待,等待该线程释放所有锁,即counter递减到0为止
# 同进程的一样
#
# Semaphore管理一个内置的计数器,
# 每当调用acquire()时内置计数器-1;
# 调用release() 时内置计数器+1;
# 计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。
# 实例:(同时只有5个线程可以获得semaphore,即可以限制最大连接数为9)
#与进程池是完全不同的概念,进程池Pool(4),最大只能产生4个进程,而且从头到尾都只是这四个进程,不会产生新的,而信号量是产生一堆线程/进程
from threading import Thread,Semaphore
import threading
import time
def func():
if sm.acquire():
print (threading.currentThread().getName() + ' get semaphore')
time.sleep(2)
sm.release()
def func():
sm.acquire()
print('%s get sm' %threading.current_thread().getName())
time.sleep(3)
sm.release()
if __name__ == '__main__':
sm=Semaphore(9)
for i in range(23):
t=Thread(target=func)
t.start()
print(threading.active_count())
定时器,指定n秒后执行某操作
from threading import Timer
def work5():
print("in work5.......")
if __name__ == '__main__':
t=Timer(2,work5)
t.start()