Python 다 중 스 레 드 원리 와 용법 사례 분석

본 논문 의 사례 는 Python 다 중 스 레 드 원리 와 용법 을 서술 하 였 다.여러분 께 참고 하도록 공유 하 겠 습 니 다.구체 적 으로 는 다음 과 같 습 니 다.
먼저 밤 을 보 겠 습 니 다.
다음은 I/O 비적 형의 스 레 드 를 살 펴 보고 밤 을 들 어 파충류,다음은 기어 내 려 온 그림 을 4 개의 스 레 드 로 파일 을 쓴다.

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
import urllib
import threading
import Queue
import timeit
def getHtml(url):
  html_page = urllib.urlopen(url).read()
  return html_page
#         URL
def getUrl(html):
  pattern = r'src="(http://img.*?)"' #      
  imgre = re.compile(pattern)
  imglist = re.findall(imgre, html) # re.findall(pattern,string)  string             ,        
  return imglist
class getImg(threading.Thread):
  def __init__(self, queue, thread_name=0): #         
    threading.Thread.__init__(self)
    self.queue = queue
    self.thread_name = thread_name
    self.start() #     
  #            
  def run(self):
    global count
    while (True):
      imgurl = self.queue.get() #        get()              
      urllib.urlretrieve(imgurl, 'E:\mnt\girls\%s.jpg' % count)
      count += 1
      if self.queue.empty():
        break
      self.queue.task_done() #          task_done()          、          ,               。
imglist = []
def main():
  global imglist
  url = "http://huaban.com/favorite/beauty/" #        
  html = getHtml(url)
  imglist = getUrl(html)
def main_1():
  global count
  threads = []
  count = 0
  queue = Queue.Queue()
  #          
  for img in imglist:
    queue.put(img)
  #        
  for i in range(4):
    thread = getImg(queue, i)
    threads.append(thread)
  #     ,        
  for thread in threads:
    thread.join()
if __name__ == '__main__':
  main()
  t = timeit.Timer(main_1)
  print t.timeit(1)

4 개의 스 레 드 의 실행 시간 은 0.421320716723 초 입 니 다.
main 수정1.단일 스 레 드 로 바 꾸 기:

def main_1():
  global count
  threads = []
  count = 0
  queue = Queue.Queue()
  #          
  for img in imglist:
    queue.put(img)
  #        
  for i in range(1):
    thread = getImg(queue, i)
    threads.append(thread)
  #     ,        
  for thread in threads:
    thread.join()

단일 라인 의 실행 시간 은 1.35626623274 초 입 니 다.

하나 더 보기:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import timeit
def countdown(n):
  while n > 0:
    n -= 1
def task1():
  COUNT = 100000000
  thread1 = threading.Thread(target=countdown, args=(COUNT,))
  thread1.start()
  thread1.join()
def task2():
  COUNT = 100000000
  thread1 = threading.Thread(target=countdown, args=(COUNT // 2,))
  thread2 = threading.Thread(target=countdown, args=(COUNT // 2,))
  thread1.start()
  thread2.start()
  thread1.join()
  thread2.join()
if __name__ == '__main__':
  t1 = timeit.Timer(task1)
  print "countdown in one thread ", t1.timeit(1)
  t2 = timeit.Timer(task2)
  print "countdown in two thread ", t2.timeit(1)

task 1 은 단일 스 레 드 이 고 task 2 는 이중 스 레 드 입 니 다.제 4 핵 기계 에서 의 실행 결과:
countdown in one thread  3.59939150155
countdown in two thread  9.87704289712
어머나,이중 스 레 드 가 단일 스 레 드 계산 보다 2 배 이상 느 린 이 유 는 무엇 일 까요?countdown 은 CPU 밀집 형 임무 이기 때 문 입 니 다.

I/O 밀집 형 작업:스 레 드 가 I/O 처 리 를 할 때 GIL 을 방출 하고 다른 스 레 드 는 GIL 을 얻 습 니 다.이 스 레 드 가 I/O 작업 을 할 때 GIL 을 방출 합 니 다.이렇게 왕복 합 니 다.
CPU 밀집 형 작업:다 중 핵 다 중 스 레 드 에서 단일 핵 다 중 스 레 드 보다 더 나 쁜 이 유 는 단일 핵 다 중 스 레 드 입 니 다.매번 GIL 을 방출 할 때마다 깨 우 는 모든 스 레 드 에서 GIL 자 물 쇠 를 얻 을 수 있 기 때문에 빈 틈 없 이 실행 할 수 있 습 니 다(단일 핵 다 중 스 레 드 의 본질은 순서대로 실행 하 는 것 입 니 다).그러나 다 중 핵,CPU 0 에서 GIL 을 방출 하면 다른 CPU 의 스 레 드 가 경쟁 합 니 다.그러나 GIL 은 곧 CPU 0(CPU 0 에서 한 스 레 드 가 아 닐 수 있 음)에 의 해 다시 가 져 올 수 있 습 니 다.다른 몇 개의 CPU 에서 깨 어 난 스 레 드 는 전환 시간 까지 기 다 렸 다가 다시 대기 상태 에 들 어 갈 수 있 습 니 다.그러면 스 레 드 가 흔 들 리 고(thrashing)효율 이 낮 습 니 다.
더 많은 파 이 썬 관련 내용 에 관심 이 있 는 독자 들 은 본 사이트 의 주 제 를 볼 수 있다.
본 논문 에서 말 한 것 이 여러분 의 Python 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기