简单来说就是操作系统可以同时运行多个任务
并发:任务数大于CPU核数,通过操作系统的各种任务调度算法,实现多个任务‘一起’执行,比如在单核CPU下需要同时处理3个任务,这就是并发,单核CPU在开启任务一会立马开启任务二,任务三也同理,这段时间内交替执行任务的方式就是并发。此外单核CPU只会存在并发的情况,不存在并行的情况。
并行:就是在同一时刻一起执行多个任务,比如你有8核的CPU,每个CPU执行一个任务,其中任务数<=CPU核数,就可以进行并行的多任务执行
同步:同步是指完成事务的逻辑顺序执行的,即先执行第一个事务,如果阻塞了,会一直等待,直到这个事务完成以后在执行第二个事务。
异步:异步和同步是相对的,异步是指在调用这个事务以后,不会等待这个事务的处理结果,直接处理第二个事务去,通过状态,通知,回调来通知调用者处理结果
# _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()
# 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了 累计次数越多 误差越大
# 互斥锁 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()