1 # 1.线程和进程的区别?
2 # 进程 -> 资源的集合
3 # 线程 -> 操作cpu的最小调度单位
4 # 进程和线程谁快? 无法比
5 # 进程至少包含一个线程,进程需要靠线程启动
6 # 线程之间内存是共享的,线程同时修改同一份数据时需要加锁 互斥锁
7 # 递归锁->锁中有锁
8 # 2.join等待线程执行结束 启动线程的语法
9 # def run():
10 # ...
11 # t_joins = []
12 # for i in range(10):
13 # t = threading.Thread(target=run, args("arg", ))
14 # t_joins.append(t)
15 # t.start()
16 # for t in t_joins:
17 # t.join() #等待线程执行结束,线程之间是独立运行的
18 # 3.守护线程:
19 # for i in range(10):
20 # t = threading.Thread(target=run, args("arg", ))
21 # t.setDaemon(True) #设置守护线程
22 # t.start()
23 # 4.队列:
24 # 解耦,使程序松耦合
25 # 提高运行效率
26 # queue.Queue#FIFO
27 # queue.LifoQueue#last come first out
28 # queue.PriorityQueue
29 # 生产者消费者模型->解耦
30 # 5.事件 Event
31 #
32 # 6.python的多线程是利用了cpu上下文切换的优势:单线程上下文切换
33 # io操作不占用cpu : 读取数据
34 # 计算占用cpu :
35 # 线程的切换需要来回切换上下文,python的多线程不适合cpu密集型操作的任务,适合io操作密集的任务
36 #
37 # 7.多进程:进程之间无GIL概念 数据不可共享 是相互独立的 ->折中的解决
38 # 八核->同一时间同时只能做八个任务(进程)
39 #
40
41 #######################################################################################
42 # 1.如何开启一段进程
43 # import multiprocessing
44 # import time,threading
45 #
46 # def thread_run():
47 # print(threading.get_ident()) #获取当前线程号
48 #
49 # def run(n):
50 # print("start processing %s" % n)
51 # t = threading.Thread(target=thread_run)
52 # t.start()
53 # # time.sleep(1)
54 # if __name__ == "__main__":
55 # for i in range(10):
56 # process = multiprocessing.Process(target=run, args=("进程%s" %i, ))
57 # process.start()
58 # # process.join()
59
60 #######################################################################################
61 # 2.如何获取进程ID
62 # from multiprocessing import Process
63 # import os
64 # def info(title):
65 # print(title)
66 # print("module name:", __name__)
67 # print("parent process,", os.getppid())
68 # print("process id", os.getpid())
69 # print("\n\n")
70 #
71 # def f(name):
72 # info('\033[31;1mfunction\033[0m')
73 # print('hello', name)
74 #
75 # if __name__ == '__main__':
76 # info('\033[32;1mmain process line\033[0m')
77 # p = Process(target=f, args=('bob',))
78 # p.start()
79 # p.join()
80
81 #######################################################################################
82 # 3.进程间如何通讯
83 # 3.1 Queue形式
84 # from multiprocessing import Process, Queue
85 # import threading, queue
86 #
87 # def f(q):
88 # q.put([42, None, 'hello'])
89 #
90 # if __name__ == '__main__':
91 # '''进程间的queue 数据共享'''
92 # q = Queue()
93 # p = Process(target=f, args=(q,))
94 # '''线程间的数据共享'''
95 # # q = queue.Queue()
96 # # p = threading.Thread(target=f, args=(q,))
97 # '''进程间数据不能用线程间共享'''
98 # # q = queue.Queue()
99 # # p = Process(target=f, args=(q,))
100 # p.start()
101 # print(q.get()) # prints "[42, None, 'hello']"
102 # p.join()
103 # # 进程间的数据共享和线程间的数据共享不是一回事 线程间的数据共享是同一份数据 进程间的数据共享其实是通过pikle序列化和反序列化克隆后的结果
104 # 3.2管道形式 pipe
105 # from multiprocessing import Process, Pipe
106 #
107 # def f(conn):
108 # conn.send([42, None, 'hello from child'])
109 # conn.send([42, None, 'hello from child'])
110 # conn.close()
111 #
112 # if __name__ == '__main__':
113 # parent_conn, child_conn = Pipe() #管道两遍分别交给两边
114 # p = Process(target=f, args=(child_conn,))
115 # p.start()
116 # print(parent_conn.recv()) # prints "[42, None, 'hello']"
117 # print(parent_conn.recv())
118 # p.join()
119
120 # 3.3Manager完全同步(真正的共享,且不需要加锁,manager中已经加锁)
121 # from multiprocessing import Process, Manager
122 # import os
123 #
124 # def f(d, l):
125 # # d[1] = '1'
126 # # d['2'] = 2
127 # # d[0.25] = None
128 # # l.append(1)
129 # d[os.getpid()] = os.getpid()
130 # l.append(os.getpid())
131 # print(l)
132 #
133 # if __name__ == '__main__':
134 # with Manager() as manager: #赋值变量
135 # d = manager.dict() #生成一个字典,可在多个进程间共享和传递
136 #
137 # l = manager.list(range(5)) #生成列表,可在多个进程间共享和传递
138 # p_list = []
139 # for i in range(10):
140 # p = Process(target=f, args=(d, l))
141 # p.start()
142 # p_list.append(p)
143 # for res in p_list: #等待结果
144 # res.join()
145 #
146 # print(d)
147 # print(l)
148
149 # 3.4 进城同步 因为屏幕共享 控制屏幕打印不会乱
150 # 起一个进程相当于克隆一份父进程的数据 开销很大
151 # from multiprocessing import Process, Lock
152 #
153 # def f(l, i):
154 # l.acquire()
155 # try:
156 # print('hello world', i)
157 # finally:
158 # l.release()
159 #
160 # if __name__ == '__main__':
161 # lock = Lock()
162 #
163 # for num in range(10):
164 # Process(target=f, args=(lock, num)).start()
165
166 #######################################################################################
167 # 4.进程池 避免进程太多 开销太大
168 # apply:串行
169 # apply_async:并行
170 # from multiprocessing import Process, Pool
171 # import time,os
172 #
173 # def Foo(i):
174 # time.sleep(2)
175 # print("in process ",os.getpid())
176 # return i + 100
177 #
178 # def Bar(arg):
179 # print("子进程中pid:", os.getpid())
180 # print('-->exec done:', arg) #回调函数是父进程调用的 可以避免子进程的多次连接数据库等等 提高效率
181 # if __name__ == "__main__": #为了区分你是主动执行这个脚本还是通过模块去调用 手动执行脚本 __name__为main 用模块调用则是模块名 测试用
182 # pool = Pool(processes=5) #允许进程池同时放入五个进程 多余的将会排队不会被执行
183 # print("主进程中pid:",os.getpid())
184 # for i in range(10):
185 # pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback回调执行完后执行
186 # # pool.apply(func=Foo, args=(i,)) #往进程池里放一个进程
187 #
188 # pool.close()
189 # pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
190 # print('end')