python threading模块

  1 # http://www.runoob.com/python3/python3-multithreading.html
  2 # https://docs.python.org/3/library/threading.html
  3 # http://yoyzhou.github.io/blog/2013/02/28/python-threads-synchronization-locks/
  4 # http://www.jb51.net/article/119414.htm
  5 # http://blog.csdn.net/tomato__/article/details/46606045
  6 # https://www.cnblogs.com/Ajen-lq/p/5325827.html
  7 
  8 
  9 import threading  # module
 10 import socket
 11 import random
 12 import time
 13 import queue
 14 import requests
 15 
 16 
 17 # ['get_ident',           1、返回线程号,一个数字
 18 #  'active_count',        2、存活的线程数
 19 #  'Condition',           3、条件锁
 20 #  'current_thread',      4、返回当前线程的对象
 21 #  'enumerate',           5、存活线程的列表
 22 #  'main_thread',         6、返回主线程对象,python解释器启动的线程
 23 #  'TIMEOUT_MAX',
 24 #  'Event',               8、事件锁
 25 #  'Lock',                9、互斥锁
 26 #  'RLock',               10、重入锁,递归锁
 27 #  'Semaphore',           11、信号量锁
 28 #  'BoundedSemaphore',    12、有限信号量类
 29 #  'Thread',              13、线程
 30 #  'Barrier',             14、栅栏
 31 #  'BrokenBarrierError',
 32 #  'Timer',               16、定时任务
 33 #  'ThreadError',
 34 #  'setprofile',
 35 #  'settrace',
 36 #  'local',               20、
 37 #  'stack_size']
 38 # Python线程同步机制: Locks, RLocks, Semaphores, Conditions, Events和Queues
 39 
 40 
 41 # 1、get_ident
 42 def foo():
 43     print('threading identify no: %s' % threading.get_ident())
 44 
 45 
 46 t1 = threading.Thread(target=foo)
 47 t2 = threading.Thread(target=foo)
 48 t3 = threading.Thread(target=foo)
 49 t1.start()
 50 t2.start()
 51 t3.start()
 52 t1.join()
 53 t2.join()
 54 t3.join()
 55 
 56 
 57 # 2、active_count
 58 def foo():
 59     time.sleep(1)
 60 
 61 
 62 t1 = threading.Thread(target=foo)
 63 t2 = threading.Thread(target=foo)
 64 t3 = threading.Thread(target=foo)
 65 t1.start()
 66 print(threading.active_count())    # 2
 67 t2.start()
 68 print(threading.active_count())    # 3
 69 t3.start()
 70 print(threading.active_count())    # 4
 71 t1.join()
 72 t2.join()
 73 t3.join()
 74 
 75 
 76 # 3、Condition 一个线程等待特定条件,而另一个线程发出特定条件满足的信号
 77 # class Condition(builtins.object) Class that implements a condition variable.
 78 # A condition variable allows one or more threads to wait until they are notified by another thread.
 79 # notify(self, n=1) Wake up one or more threads waiting on this condition, if any.
 80 # notify_all(self) Wake up all threads waiting on this condition.
 81 # wait(self, timeout=None) Wait until notified or until a timeout occurs.
 82 # wait_for(self, predicate, timeout=None) Wait until a condition evaluates to True.
 83 # wait()方法释放锁,然后阻塞直到另一个线程调用notify()或者notify_all()唤醒它。唤醒后,wait()重新获取锁并返回。它也可以指定一个超时时间。
 84 # notify()方法唤醒等待线程中的一个;notify_all()方法唤醒所有等待线程。
 85 # 注意:notify()和notify_all()方法不释放锁;这意味着唤醒的线程或者线程组将不会从wait()调用中立即返回。
 86 # 一个条件变量允许一个或多个线程等待,直到他们被另一个线程通知。
 87 # wait()一旦唤醒或者超时,它重新请求锁并返回。
 88 
 89 
 90 class Producer(threading.Thread):
 91 
 92     def __init__(self, integers, condition):
 93         threading.Thread.__init__(self)
 94         self.integers = integers
 95         self.condition = condition
 96 
 97     def run(self):
 98         while True:
 99             integer = random.randint(0, 256)
100             with self.condition:  # 获取条件锁
101                 print('condition acquired by %s' % self.name)
102                 self.integers.append(integer)
103                 print('%d appended to list by %s' % (integer, self.name))
104                 print('condition notified by %s' % self.name)
105                 self.condition.notify()    # 唤醒消费者线程
106                 print('condition released by %s' % self.name)
107             time.sleep(1)  # 暂停1秒钟
108 
109 
110 class Consumer(threading.Thread):
111     def __init__(self, integers, condition):
112         threading.Thread.__init__(self)
113         self.integers = integers
114         self.condition = condition
115 
116     def run(self):
117         while True:
118             with self.condition:  # 获取条件锁
119                 print('condition acquired by %s' % self.name)
120                 while True:
121                     if self.integers:  # 判断是否有整数
122                         integer = self.integers.pop()
123                         print('%d popped from list by %s' % (integer, self.name))
124                         break
125                     print('condition wait by %s' % self.name)
126                     self.condition.wait()  # 等待商品,并且释放资源让生产者执行
127                 print('condition released by %s' % self.name)
128 
129 
130 def main():
131     integers = []
132     condition = threading.Condition()
133     t1 = Producer(integers, condition)
134     t2 = Consumer(integers, condition)
135     t1.start()
136     t2.start()
137     t1.join()
138     t2.join()
139 
140 
141 main()
142 
143 
144 # 4、current_thread
145 def foo():
146     print(threading.current_thread())
147 
148 
149 t1 = threading.Thread(target=foo)
150 t1.start()
151 t1.join()
152 
153 
154 # 5、enumerate
155 def foo():
156     time.sleep(1)
157 
158 
159 t1 = threading.Thread(target=foo)
160 t2 = threading.Thread(target=foo)
161 t3 = threading.Thread(target=foo)
162 t1.start()
163 t2.start()
164 t3.start()
165 print(threading.enumerate())
166 t1.join()
167 t2.join()
168 t3.join()
169 
170 
171 # 6、main_thread
172 def foo():
173     time.sleep(1)
174 
175 
176 t1 = threading.Thread(target=foo)
177 t1.start()
178 print(threading.main_thread())
179 t1.join()
180 
181 
182 # 8、Event 事件锁 一个线程发送/传递事件,另外的线程(多线程)等待事件的触发。
183 # class Event(builtins.object) Class implementing event objects.
184 # Events manage a flag that can be set to true with the set() method and reset to false with the clear() method.
185 # The wait() method blocks until the flag is true.  The flag is initially false.
186 # set(self) Set the internal flag to true. All threads waiting for it to become true are awakened.
187 #           Threads that call wait() once the flag is true will not block at all.
188 # clear(self) Reset the internal flag to false.
189 # is_set(self) Return true if and only if the internal flag is true.
190 # wait(self, timeout=None) Block until the internal flag is true.
191 # isSet = is_set(self)
192 
193 
194 class Producer(threading.Thread):
195     def __init__(self, integers, event):
196         threading.Thread.__init__(self)
197         self.integers = integers
198         self.event = event
199 
200     def run(self):
201         while True:
202             integer = random.randint(0, 256)
203             self.integers.append(integer)
204             print('%d appended to list by %s' % (integer, self.name))
205             print('event set by %s' % self.name)
206             self.event.set()            # 设置事件
207             self.event.clear()          # 发送事件
208             print('event cleared by %s' % self.name)
209             time.sleep(1)
210 
211 
212 class Consumer(threading.Thread):
213     def __init__(self, integers, event):
214         threading.Thread.__init__(self)
215         self.integers = integers
216         self.event = event
217 
218     def run(self):
219         while True:
220             self.event.wait()      # 等待事件被触发
221             # self.event.wait(timeout=2)  # 等待事件被触发,超时之后,不再阻塞,继续执行
222             try:
223                 integer = self.integers.pop()
224                 print('%d popped from list by %s' % (integer, self.name))
225             except IndexError:
226                 # catch pop on empty list
227                 time.sleep(1)
228 
229 
230 def main():
231     integers = []
232     event = threading.Event()
233     t1 = Producer(integers, event)
234     t2 = Consumer(integers, event)
235     t1.start()
236     t2.start()
237     t1.join()
238     t2.join()
239 
240 
241 main()
242 
243 
244 # 9、Lock互斥锁
245 # class lock(builtins.object) A lock object is a synchronization primitive. To create a lock, call threading.Lock().
246 # acquire() -- lock the lock, possibly blocking until it can be obtained
247 # release() -- unlock of the lock
248 # locked() -- test whether the lock is currently locked
249 # acquire(...) acquire_lock(...) acquire(blocking=True, timeout=-1)
250 # locked(...) locked_lock(...) locked() -> bool
251 # release(...) release_lock(...) release()
252 
253 
254 class FetchUrls(threading.Thread):
255     def __init__(self, urls, output, lock):
256         threading.Thread.__init__(self)
257         self.urls = urls
258         self.output = output
259         self.lock = lock
260 
261     def run(self):
262         while self.urls:
263             url = self.urls.pop()
264             req = requests.get(url)
265             with self.lock:
266                 self.output.write(req.content)
267             print('write done by %s' % self.name)
268             print('URL %s fetched by %s' % (url, self.name))
269 
270 
271 def main():
272     lock = threading.Lock()
273     urls1 = ['http://www.baidu.com', 'http://www.sina.com']
274     urls2 = ['http://www.sohu.com', 'http://www.youku.com']
275     f = open('output.txt', 'wb+')
276     t1 = FetchUrls(urls1, f, lock)
277     t2 = FetchUrls(urls2, f, lock)
278     t1.start()
279     t2.start()
280     t1.join()
281     t2.join()
282     f.close()
283 
284 
285 main()
286 
287 
288 # 10、RLock可重入锁
289 # RLock是可重入锁(reentrant lock),acquire()能够不被阻塞的被同一个线程调用多次。要注意的是release()需要调用与acquire()相同的次数才能释放锁。
290 
291 
292 # 11、Semaphore信号量锁
293 # 信号量同步基于内部计数器,每调用一次acquire(),计数器减1;每调用一次release(),计数器加1.当计数器为0时,acquire()调用被阻塞。
294 # class Semaphore(builtins.object) This class implements semaphore objects.
295 # Semaphores manage a counter representing the number of release() calls minus the number of acquire() calls, plus an initial value.
296 # The acquire() method blocks if necessary until it can return without making the counter negative.
297 # If not given, value defaults to 1.
298 # acquire(self, blocking=True, timeout=None) Acquire a semaphore, decrementing the internal counter by one. 超时或者不阻塞返回false
299 # release(self) Release a semaphore, incrementing the internal counter by one.
300 
301 
302 class MyThread(threading.Thread):
303     def __init__(self, semaphore, list_):
304         threading.Thread.__init__(self)
305         self.semaphore = semaphore
306         self.list_ = list_
307 
308     def run(self):
309         with self.semaphore:
310             self.list_.append(2)
311 
312 
313 def main():
314     list_ = [1, 2, 3]
315     semaphore = threading.Semaphore(2)    # 允许同时2个线程访问共享资源,默认是1
316     t1 = MyThread(semaphore, list_)
317     t2 = MyThread(semaphore, list_)
318     t3 = MyThread(semaphore, list_)
319     t1.start()
320     t2.start()
321     t3.start()
322     t1.join()
323     t2.join()
324     t3.join()
325     print(list_)
326 
327 
328 main()
329 
330 
331 # 12、BoundedSemaphore有限信号量类
332 # “有限”(bounded)信号量类,可以确保release()方法的调用次数不能超过给定的初始信号量数值(value参数)
333 # 重写release方法
334 # If the number of releases exceeds the number of acquires, raise a ValueError.
335 
336 
337 # 13、Thread
338 # class Thread(builtins.object) A class that represents a thread of control.
339 # This class can be safely subclassed in a limited fashion. There are two ways to specify the activity:
340 # by passing a callable object to the constructor, or by overriding the run() method in a subclass.
341 # __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)
342 # group 为将来线程组扩展留的
343 # daemon 默认非守护线程
344 # getName(self)  方法
345 # isDaemon(self) 方法
346 # is_alive(self) 是否存活,run开始之后到run结束之前是True
347 # join(self, timeout=None) Wait until the thread terminates.
348 # run(self) Method representing the thread's activity.
349 # setDaemon(self, daemonic)
350 # setName(self, name)
351 # start(self)
352 # daemon 属性
353 # ident  属性
354 # name   属性
355 
356 # 无join,无daemon
357 def foo():
358     time.sleep(3)
359 
360 
361 t1 = threading.Thread(target=foo)
362 t1.start()
363 print('main thread go on')  # 最后再等待线程,释放线程的资源,这里阻塞
364 
365 
366 # 有join
367 def foo():
368     time.sleep(3)
369 
370 
371 t1 = threading.Thread(target=foo)
372 t1.start()
373 t1.join()   # 等待线程结束,抓线程再继承执行,这里阻塞
374 print('main thread not go on')
375 
376 
377 # 有daemon
378 def foo():
379     while True:
380         print('abc')
381 
382 
383 t1 = threading.Thread(target=foo)
384 t1.setDaemon(True)
385 t1.start()
386 print('main thread go on')   # 主线程结束,要求子线程同时也结束,这里不阻塞了
387 
388 
389 # 14、Barrier
390 # class Barrier(builtins.object) Implements a Barrier. Useful for synchronizing a fixed number
391 # of threads at known synchronization points.
392 # Threads block on 'wait()' and are simultaneously once they have all made that call.
393 # __init__(self, parties, action=None, timeout=None)
394 # abort(self) Place the barrier into a 'broken' state.     方法,终止栅栏,wait会抛出异常
395 # reset(self) Reset the barrier to the initial state.      方法,恢复栅栏
396 # wait(self, timeout=None) Wait for the barrier.           方法,等待数量达到parties,一起通过栅栏
397 # broken Return True if the barrier is in a broken state.                    属性,检查栅栏的状态,True是坏
398 # n_waiting Return the number of threads currently waiting at the barrier.   属性,正在wait的数量
399 # parties Return the number of threads required to trip the barrier.         属性,parties的数量
400 
401 
402 def server(b):
403     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
404     s.bind(("192.168.99.156", 5003))
405     s.listen(5)
406 
407     while True:
408         # print(b.broken)   # False
409         # b.abort()
410         # print(b.broken)   # True
411         # b.reset()
412 
413         b.wait()
414         print(threading.get_ident())
415         new_socket, client_addr = s.accept()
416         new_socket.sendall(bytes("Hello world", encoding="utf-8"))
417         new_socket.close()
418         time.sleep(3)
419 
420 
421 def client(b):
422     while True:
423         b.wait()       # 超时 raise BrokenBarrierError
424         print(threading.get_ident())
425         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
426         s.connect(("192.168.99.156", 5003))
427         ret = str(s.recv(1024), encoding="utf-8")
428         print(ret)
429         time.sleep(0.1)
430 
431 
432 def callback():
433     print('Barrier')
434 
435 
436 def main():
437     b = threading.Barrier(2, action=callback, timeout=5)        # 超时 raise BrokenBarrierError, 通过一次栅栏调用一次action
438     t1 = threading.Thread(target=server, args=(b, ))
439     t2 = threading.Thread(target=client, args=(b, ))
440     t1.start()
441     t2.start()
442     t1.join()
443     t2.join()
444 
445 
446 main()
447 
448 
449 # 16、Timer定时任务
450 # class Timer(Thread) Call a function after a specified number of seconds。
451 # __init__(self, interval, function, args=None, kwargs=None) 继承Thread
452 # 新增方法:cancel(self)
453 # 重写方法:run(self)
454 # 其他方法同Thread
455 
456 
457 def func():
458     print('abc')
459 
460 
461 def main():
462     t = threading.Timer(2, func)
463     t.start()
464 
465 
466 main()
467 
468 
469 # 20、local
470 localVal = threading.local()
471 localVal.val = "Main-Thread"   # 每个线程单独创建内存空间来存储
472 a = 10
473 
474 
475 def print_student():
476     global a
477     print('%s (in %s)' % (localVal.val, threading.current_thread().name))
478     a += 100                   # 操作的是主线程的变量
479 
480 
481 def print_thread(name):
482     localVal.val = name        # 每个线程单独创建内存空间来存储
483     print_student()
484 
485 
486 def main():
487     t1 = threading.Thread(target=print_thread, args=('One',), name='Thread-A')
488     t2 = threading.Thread(target=print_thread, args=('Two',), name='Thread-B')
489     t1.start()
490     t2.start()
491     t1.join()
492     t2.join()
493     print(localVal.val)
494     print(a)
495 
496 
497 main()
498 
499 
500 # 21、使用队列同步线程间共享资源
501 # 队列 Queue
502 class Producer(threading.Thread):
503     def __init__(self, q):
504         threading.Thread.__init__(self)
505         self.queue_ = q
506 
507     def run(self):
508         while True:
509             integer = random.randint(0, 256)
510             self.queue_.put(integer)  # 将生成的整数添加到队列
511             print('%d put to queue by %s' % (integer, self.name))
512             time.sleep(1)
513 
514 
515 class Consumer(threading.Thread):
516     def __init__(self, q):
517         threading.Thread.__init__(self)
518         self.queue_ = q
519 
520     def run(self):
521         while True:
522             integer = self.queue_.get()
523             print('%d popped from list by %s' % (integer, self.name))
524             self.queue_.task_done()
525 
526 
527 def main():
528     q = queue.Queue(20)
529     t1 = Producer(q)
530     t2 = Consumer(q)
531     t1.start()
532     t2.start()
533     t1.join()
534     t2.join()
535 
536 
537 main()

 

posted @ 2018-01-17 11:16  魂~  阅读(330)  评论(0编辑  收藏  举报