# 1.线程和进程的区别?
# 进程 -> 资源的集合
# 线程 -> 操作cpu的最小调度单位
# 进程和线程谁快? 无法比
# 进程至少包含一个线程,进程需要靠线程启动
# 线程之间内存是共享的,线程同时修改同一份数据时需要加锁 互斥锁
# 递归锁->锁中有锁
# 2.join等待线程执行结束 启动线程的语法
# def run():
# ...
# t_joins = []
# for i in range(10):
# t = threading.Thread(target=run, args("arg", ))
# t_joins.append(t)
# t.start()
# for t in t_joins:
# t.join() #等待线程执行结束,线程之间是独立运行的
# 3.守护线程:
# for i in range(10):
# t = threading.Thread(target=run, args("arg", ))
# t.setDaemon(True) #设置守护线程
# t.start()
# 4.队列:
# 解耦,使程序松耦合
# 提高运行效率
# queue.Queue#FIFO
# queue.LifoQueue#last come first out
# queue.PriorityQueue
# 生产者消费者模型->解耦
# 5.事件 Event
#
# 6.python的多线程是利用了cpu上下文切换的优势:单线程上下文切换
# io操作不占用cpu : 读取数据
# 计算占用cpu :
# 线程的切换需要来回切换上下文,python的多线程不适合cpu密集型操作的任务,适合io操作密集的任务
#
# 7.多进程:进程之间无GIL概念 数据不可共享 是相互独立的 ->折中的解决
# 八核->同一时间同时只能做八个任务(进程)
#
#######################################################################################
# 1.如何开启一段进程
# import multiprocessing
# import time,threading
#
# def thread_run():
# print(threading.get_ident()) #获取当前线程号
#
# def run(n):
# print("start processing %s" % n)
# t = threading.Thread(target=thread_run)
# t.start()
# # time.sleep(1)
# if __name__ == "__main__":
# for i in range(10):
# process = multiprocessing.Process(target=run, args=("进程%s" %i, ))
# process.start()
# # process.join()
#######################################################################################
# 2.如何获取进程ID
# from multiprocessing import Process
# import os
# def info(title):
# print(title)
# print("module name:", __name__)
# print("parent process,", os.getppid())
# print("process id", os.getpid())
# print("\n\n")
#
# def f(name):
# info('\033[31;1mfunction\033[0m')
# print('hello', name)
#
# if __name__ == '__main__':
# info('\033[32;1mmain process line\033[0m')
# p = Process(target=f, args=('bob',))
# p.start()
# p.join()
#######################################################################################
# 3.进程间如何通讯
# 3.1 Queue形式
# from multiprocessing import Process, Queue
# import threading, queue
#
# def f(q):
# q.put([42, None, 'hello'])
#
# if __name__ == '__main__':
# '''进程间的queue 数据共享'''
# q = Queue()
# p = Process(target=f, args=(q,))
# '''线程间的数据共享'''
# # q = queue.Queue()
# # p = threading.Thread(target=f, args=(q,))
# '''进程间数据不能用线程间共享'''
# # q = queue.Queue()
# # p = Process(target=f, args=(q,))
# p.start()
# print(q.get()) # prints "[42, None, 'hello']"
# p.join()
# # 进程间的数据共享和线程间的数据共享不是一回事 线程间的数据共享是同一份数据 进程间的数据共享其实是通过pikle序列化和反序列化克隆后的结果
# 3.2管道形式 pipe
# from multiprocessing import Process, Pipe
#
# def f(conn):
# conn.send([42, None, 'hello from child'])
# conn.send([42, None, 'hello from child'])
# conn.close()
#
# if __name__ == '__main__':
# parent_conn, child_conn = Pipe() #管道两遍分别交给两边
# p = Process(target=f, args=(child_conn,))
# p.start()
# print(parent_conn.recv()) # prints "[42, None, 'hello']"
# print(parent_conn.recv())
# p.join()
# 3.3Manager完全同步(真正的共享,且不需要加锁,manager中已经加锁)
# from multiprocessing import Process, Manager
# import os
#
# def f(d, l):
# # d[1] = '1'
# # d['2'] = 2
# # d[0.25] = None
# # l.append(1)
# d[os.getpid()] = os.getpid()
# l.append(os.getpid())
# print(l)
#
# if __name__ == '__main__':
# with Manager() as manager: #赋值变量
# d = manager.dict() #生成一个字典,可在多个进程间共享和传递
#
# l = manager.list(range(5)) #生成列表,可在多个进程间共享和传递
# p_list = []
# for i in range(10):
# p = Process(target=f, args=(d, l))
# p.start()
# p_list.append(p)
# for res in p_list: #等待结果
# res.join()
#
# print(d)
# print(l)
# 3.4 进城同步 因为屏幕共享 控制屏幕打印不会乱
# 起一个进程相当于克隆一份父进程的数据 开销很大
# from multiprocessing import Process, Lock
#
# def f(l, i):
# l.acquire()
# try:
# print('hello world', i)
# finally:
# l.release()
#
# if __name__ == '__main__':
# lock = Lock()
#
# for num in range(10):
# Process(target=f, args=(lock, num)).start()
#######################################################################################
# 4.进程池 避免进程太多 开销太大
# apply:串行
# apply_async:并行
# from multiprocessing import Process, Pool
# import time,os
#
# def Foo(i):
# time.sleep(2)
# print("in process ",os.getpid())
# return i + 100
#
# def Bar(arg):
# print("子进程中pid:", os.getpid())
# print('-->exec done:', arg) #回调函数是父进程调用的 可以避免子进程的多次连接数据库等等 提高效率
# if __name__ == "__main__": #为了区分你是主动执行这个脚本还是通过模块去调用 手动执行脚本 __name__为main 用模块调用则是模块名 测试用
# pool = Pool(processes=5) #允许进程池同时放入五个进程 多余的将会排队不会被执行
# print("主进程中pid:",os.getpid())
# for i in range(10):
# pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback回调执行完后执行
# # pool.apply(func=Foo, args=(i,)) #往进程池里放一个进程
#
# pool.close()
# pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
# print('end')
进程/线程池/进程ID/进程间的通讯pipe/Queue/Manager/进程同步
最新推荐文章于 2019-03-18 11:31:40 发布