和开启进程的两种方式相似,只不过改一下导入的模块
进程与线程之间的区别:
开进程的开销远大于开线程 同一进程内多个线程共享该进程的内存空间 Pid相同
Tread 方法
from threading import Thread,currentThread,active_count,enumerateimport timedef task():print('%s is running'% currentThread().getName()) time.sleep(1)print('%s is done'% currentThread().getName())if __name__=='__main__': t = Thread(target=task,name='线程1') # name 设置线程名t.start() t.setName('线程-1') # 设置线程名print(t.getName()) # 获取线程名print(t.is_alive(),t.isAlive()) t.join() # 等待线程执行完print(t.isAlive())print(currentThread().getName()) # 获取当前线程,在主线程下获取的就是主线程名currentThread().setName('main线程') # 设置当前线程名print('主线程',currentThread().getName())print(active_count()) # 先导入active_count 查看活跃线程数目print(enumerate()) # 先导入enumerate 查看线程
守护线程
from threading import Threadimport timedef foo():print(123) time.sleep(1)print('end123')def bar():print(456) time.sleep(3)print('end456')if __name__=='__main__': t1 = Thread(target=foo) t2 = Thread(target=bar) t1.setDaemon(True) # 等价于t1.daemon = Truet1.start() t2.start()print('--main--')守护线程等到非守护线程结束才结束。
0
当两个线程互相争取对方现有的锁,就会造成死锁的现象。
可以连续acquire多次,每acquire一次计数器加1,只有计数器为0时,其他线程才可以抢到该锁。
from threading import Thread,RLockimport timemutexA = mutexB = RLock()class MyThread(Thread):def run(self):self.f1()self.f2()def f1(self): mutexA.acquire()print('%s 拿到A锁'%self.name) mutexB.acquire()print('%s 拿到B锁' % self.name) mutexB.release() mutexA.release()def f2(self): mutexB.acquire()print('%s 拿到B锁' % self.name) time.sleep(3) mutexA.acquire()print('%s 拿到A锁' % self.name) mutexA.release() mutexB.release()if __name__=='__main__':for i in range(5): t = MyThread() t.start()
Thread-1 拿到A锁
Thread-1 拿到B锁
Thread-1 拿到B锁
Thread-1 拿到A锁
Thread-2 拿到A锁
Thread-2 拿到B锁
Thread-3 拿到A锁
Thread-3 拿到B锁
Thread-3 拿到B锁
Thread-3 拿到A锁
Thread-5 拿到A锁
Thread-5 拿到B锁
Thread-2 拿到B锁
Thread-2 拿到A锁
Thread-4 拿到A锁
Thread-4 拿到B锁
Thread-5 拿到B锁
Thread-5 拿到A锁
Thread-4 拿到B锁
Thread-4 拿到A锁
有10个人上公共厕所,公共厕所只有五个坑,同一时间最多可以有五个人同时上厕所。
from threading import Thread,currentThread,Semaphoreimport time,randomsem = Semaphore(5)def task():# sem.acquire() # print('%s get'% currentThread().getName()) # sem.release()with sem: # 与上边等价,这种方式更简洁print('%s get' % currentThread().getName()) time.sleep(random.randint(1,5))print('%s out' % currentThread().getName())if __name__=='__main__':for i in range(10): t = Thread(target=task) t.start()
Thread-1 get
Thread-2 get
Thread-3 get
Thread-4 get
Thread-5 get
Thread-5 out
Thread-6 get
Thread-6 out
Thread-7 get
Thread-1 out
Thread-8 get
Thread-3 out
Thread-2 out
Thread-9 get
Thread-10 get
Thread-7 out
Thread-4 out
Thread-8 out
Thread-9 out
Thread-10 out
rose 正在听课
lucy 正在听课
lily 正在听课
luli 正在授课
luli 下课
rose 课间活动
lily 课间活动
lucy 课间活动
# from threading import Thread,Event# import time# event = Event()## def student(name):# print('%s 正在听课'% name)# event.wait() # 括号里面加上数字就是等待时间# print('%s 课间活动'% name)## def teacher(name):# print('%s 正在授课'%name)# time.sleep(7)# print('%s 下课' % name)# time.sleep(0.1)# event.set()### if __name__ == '__main__':# s1 = Thread(target=student,args=('rose',))# s2 = Thread(target=student, args=('lucy',))# s3 = Thread(target=student, args=('lily',))## t = Thread(target=teacher, args=('luli',))## s1.start()# s2.start()# s3.start()# t.start()from threading import Thread,Event,currentThreadimport timeevent = Event()def conn(): n=0while not event.is_set(): # event 是否被设置if n == 3:print('%s try too many times'% currentThread().getName())returnn += 1event.wait(0.5)print('%s try %s time'%(currentThread().getName(),n))print('%s is connected'%currentThread().getName())def check():print('%s is checking'%currentThread().getName()) time.sleep(5) event.set()if __name__ =='__main__':for i in range(3): con = Thread(target=conn) con.start() check = Thread(target=check) check.start()
Thread-4 is checking
Thread-2 try 1 time
Thread-1 try 1 time
Thread-3 try 1 time
Thread-1 try 2 time
Thread-3 try 2 time
Thread-2 try 2 time
Thread-1 try 3 time
Thread-1 try too many times
Thread-2 try 3 time
Thread-3 try 3 time
Thread-3 try too many times
Thread-2 try too many times
验证码刷新
from threading import Timerimport randomclass Code:def __init__(self):self.make_cache()def make_cache(self,interval=10):self.cache = self.make_code()print(self.cache)self.t = Timer(interval,self.make_cache) # 这个地方是函数名,如果是函数名()会报错self.t.start()def make_code(self,): res = ''for i in range(4): s1=str(random.randint(0,9)) s2 = chr(random.randint(65,90)) # 大写字母res += random.choice([s1,s2])return resdef check(self):while True: code = input('验证码:').strip()print('验证码 %s'%self.cache)print('输入:%s'% code.upper())if code.upper() == self.cache: # 不用区分大小写print('正确')self.t.cancel()breakobj = Code()obj.check()
name:id 0 pid:8892
name:id 1 pid:8892
name:id 2 pid:8892
name:id 3 pid:8892
name:id 4 pid:8892
主
以上代码实现的是线程池,如果实现进程池只要改一行代码:
Pool = ProcessPoolExecutor(4)就ok了
同步调用
from concurrent.futures import ThreadPoolExecutorimport time,randomdef work(name):print('%s is working'%name) time.sleep(random.randint(2,5)) res = random.randint(8,24)return {'name':name,'hours':res}def count(res): name = res['name'] num = res['hours']*10print('%s 制造了%s个艺术品'%(name,num))if __name__ =='__main__': pool = ThreadPoolExecutor(10) worker1 = pool.submit(work,'1').result() count(worker1) worker2 = pool.submit(work, '2').result() count(worker2) worker3 = pool.submit(work, '3').result() count(worker3)
1 is working
1 制造了120个艺术品
2 is working
2 制造了240个艺术品
3 is working
3 制造了170个艺术品
异步调用
from concurrent.futures import ThreadPoolExecutorimport time,randomdef work(name):print('%s is working'%name) time.sleep(random.randint(2,5)) res = random.randint(8,24)return {'name':name,'hours':res}def count(res): res = res.result() # future对象此时已经执行完毕,获取future对象的结果name = res['name'] num = res['hours']*10print('%s 制造了%s个艺术品'%(name,num))if __name__ =='__main__': pool = ThreadPoolExecutor(10) pool.submit(work,'1').add_done_callback(count) # 调用count方法并把结果future对象传给方法pool.submit(work, '2').add_done_callback(count) pool.submit(work, '3').add_done_callback(count)
1 is working
2 is working
3 is working
3 制造了220个艺术品
2 制造了200个艺术品
1 制造了170个艺术品
转载于:https://www.cnblogs.com/yuliangkaiyue/p/9661270.html