多线程
作者:互联网
>多线程
>>多任务
简单来说就是操作系统可以同时运行多个任务
并发:任务数大于CPU核数,通过操作系统的各种任务调度算法,实现多个任务‘一起’执行,比如在单核CPU下需要同时处理3个任务,这就是并发,单核CPU在开启任务一会立马开启任务二,任务三也同理,这段时间内交替执行任务的方式就是并发。此外单核CPU只会存在并发的情况,不存在并行的情况。
并行:就是在同一时刻一起执行多个任务,比如你有8核的CPU,每个CPU执行一个任务,其中任务数<=CPU核数,就可以进行并行的多任务执行
同步:同步是指完成事务的逻辑顺序执行的,即先执行第一个事务,如果阻塞了,会一直等待,直到这个事务完成以后在执行第二个事务。
异步:异步和同步是相对的,异步是指在调用这个事务以后,不会等待这个事务的处理结果,直接处理第二个事务去,通过状态,通知,回调来通知调用者处理结果
>>_thread模块
# _thread 实现多线程
'''
_thread 常用模块
def start_new_thread(function,args,kwargs=None) 启动一个新的线程 function 线程处理函数 args 传递给线程的参数 元组类型 kwargs 可选参数
def allocate_lock() 分配锁对象
def exit() 线程退出
def get_ident() 获取线程表示符
def interrupt_main() 终止主线程 会产生 KeyboardInterrupt异常
'''
# 利用_thread 模块创建多线程
import _thread
import time
def work(thread_name):
print('哟西 这是第%s个线程' % thread_name)
time.sleep(1)
def main():
for i in range(1,5):
_thread.start_new_thread(work,('--%s'% i,))
time.sleep(30) # 主进程添加延迟 保证子线程执行完成
if __name__ == '__main__':
main()
>>Treading模块
# threading实现多线程
'''
常用方法
def init(self,group=None,target=None,name=None,args=(),kwargs=None,*,daemon=None)
def start(self) 线程启动
def run(self) 线程操作主体 若没设置target 处理函数 则执行方法
def join(self,timeout=None)
def name(self) 获取线程名称
def ident(self) 获取线程标识
def is_alive() 判断线程存活状态
'''
# threading 创建多线程
import threading
import time
def work(thread_name):
print('哟西 这是第%s个线程' % thread_name)
time.sleep(1)
def main():
thraeds=[threading.Thread(target=work,args=('---%s'%i,))for i in range(1,5)]
for thraed in thraeds:
thraed.start()
time.sleep(3) # 主进程添加延迟 保证子线程执行完成
if __name__ == '__main__':
main()
# 获取线程信息
import threading
import time
def work(thread_name):
print('哟西 这是第%s个线程' % thread_name)
print(threading.current_thread().ident, threading.current_thread().name)
print('')
time.sleep(1)
def main():
thraeds=[threading.Thread(target=work,args=('---%s'%i,))for i in range(20)]
for thraed in thraeds:
thraed.start()
if __name__ == '__main__':
main()
# 将线程设置成类 设置守护进程
import threading
import time
class myThread(threading.Thread):
def __init__(self, threadname, delay, count):
super().__init__(name=threadname)
self._delay = delay
self._count = count
def run(self):
for num in range(self._count):
time.sleep(1)
print('线程id:%s,线程名称:%s - %s'
% (threading.current_thread().ident, threading.current_thread().getName(), num))
def main():
thr1=myThread('用户进程', 1, 10)
thr1.start()
thr2= myThread('守护进程', 1, 999)
thr2.setDaemon(True) # 将线程2 设置成守护进程
thr2.start()
if __name__ == '__main__':
main()
>>线程同步
# 线程同步&互斥锁
# Semaphore 实现资源并发控制
import threading
import time
def work_handle(sem):
if sem.acquire():
print('请%s前往窗口,办理个人业务 '% threading.current_thread().getName())
time.sleep(3) # 模拟银行办理业务时间
sem.release() # 释放资源
def main():
sem = threading.Semaphore(2)
threading_list=[threading.Thread(target=work_handle,args=(sem,),name='客户%s'% num) for num in range(10)]
for thr in threading_list:
thr.start()
if __name__ == '__main__':
main()
>>多线程共享全局变量
# 共享全局变量
import threading
num =0
def thr1():
global num
for i in range(0,1000000):
num = num+1
def thr2():
global num
for i in range(0,1000000):
num = num+1
if __name__ == '__main__':
for i in range(5):
num = 0
t1 = threading.Thread(target=thr1)
t2 = threading.Thread(target=thr2)
t1.start()
t2.start()
t1.join()
t2.join()
print('计算结果为%s' % num)
》》》计算结果为1647829
计算结果为2000000
计算结果为2000000
计算结果为1000000
计算结果为1645209
# 创建两个线程 各自加了100000次 累计输出应该是200000 调用了5次应该每次的输出应该一样的 为什么不一样呢,应为像个线程同时运行,不知到谁先谁后,累加1时,线程1 刚累加等于1 想赋值给 num 结果 线程2 提前赋值给了num 结果就是1了 累计次数越多 误差越大
&互斥锁解决资源问题(lock()和Rlock())
# 互斥锁
import threading
num =0
def thr1(lock):
lock.acquire()
global num
for i in range(0,1000000):
num = num+1
lock.release()
def thr2(lock):
lock.acquire()
global num
for i in range(0,1000000):
num = num+1
lock.release()
if __name__ == '__main__':
lock = threading.Lock()
for i in range(5):
num = 0
t1 = threading.Thread(target=thr1,args=(lock,))
t2 = threading.Thread(target=thr2,args=(lock,))
t1.start()
t2.start()
t1.join()
t2.join()
print('计算结果为%s' % num)
import threading
num =0
def thr1(lock):
lock.acquire()
global num
for i in range(0,1000000):
num = num+1
lock.release()
def thr2(lock):
lock.acquire()
global num
for i in range(0,1000000):
num = num+1
lock.release()
if __name__ == '__main__':
lock = threading.RLock()
for i in range(5):
num = 0
t1 = threading.Thread(target=thr1,args=(lock,))
t2 = threading.Thread(target=thr2,args=(lock,))
t1.start()
t2.start()
t1.join()
t2.join()
print('计算结果为%s' % num)
>>死锁
一直等待对方释放锁的情况就是死锁
# 死锁
import threading
def get_value(index,lock,list1):
lock.acquire()
if index >= len(list1):
print('超出索引范围')
return
data = list1[index]
print(data)
lock.release()
def main():
lock = threading.Lock()
for i in range(10):
t =threading.Thread(target=get_value,args=(3,lock,[1,2]))
t.start()
if __name__ == '__main__':
main()
# 解决死锁问题 可以在acquire()里面添加超时时间 超过时间自动解锁
# 死锁
import threading
def get_value(index,lock,list1):
lock.acquire(timeout=2)
if index >= len(list1):
print('超出索引范围')
return
data = list1[index]
print(data)
lock.release()
def main():
lock = threading.Lock()
for i in range(10):
t =threading.Thread(target=get_value,args=(3,lock,[1,2]))
t.start()
if __name__ == '__main__':
main()
>>定时调度
# 定时调度是一种基于线程任务的操作管理 可以实现在末段时间的任务的重复执行
# 通过sched模块实现定时调度操作
'''
delay=0 调度任务启动的延迟时间 如果是0 表示立即启动
priority=0 多个调度任务的启动优先级
action=func 设置任务的调度处理函数
argument = (参数,) 调度函数的参数 必须填可迭代对象
'''
import sched
def work_1():
print('我是第一个任务')
def work_2():
print('我是第二个任务')
def work_3():
print('我是第三个任务')
def main():
sch =sched.scheduler()
s1=sch.enter(delay=2,priority=1,action=work_1,)
s2= sch.enter(delay=6, priority=3, action=work_2)
s3 = sch.enter(delay=4, priority=2, action=work_3)
sch.run()
if __name__ == '__main__':
main()
标签:__,main,lock,threading,num,多线程,def 来源: https://www.cnblogs.com/chendakeng/p/16133159.html