'''乙個執行緒在使用這個共享的時候,其他執行緒必須等待他結束
通過"鎖"實現,作用就是防止多個執行緒使用這片記憶體空間
程序:程式的一次執行
執行緒:cpu運算的基本排程單位
多執行緒:大量密集i/o處理,在等待響應的時候,其他執行緒去工作
多程序:大量的密集平行計算
scrapy:非同步網路框架(很多協程在處理)
頁碼佇列--執行緒取頁碼爬取(採集執行緒--網路io)--資料佇列(得到的響應)--執行緒解析網頁(解析執行緒磁碟io)--解析後的資料儲存
'''# 請求
import requests
# 佇列
from multiprocessing import queue
# 執行緒
from threading import thread
import threading
# 解析
from lxml import etree
# 儲存
import json
import time
class threadcrawl(thread):
def __init__(self, threadname, pagequeue, dataqueue):
# 呼叫父類的初始化方法
super(threadcrawl, self).__init__()
self.threadname = threadname
self.pagequeue = pagequeue
self.dataqueue = dataqueue
# thread.start()會執行run方法
def run(self):
print("啟動"+self.threadname)
while not crawl_exit:
try:
# 從頁碼佇列取出乙個數字,
# 可選引數block(預設ture)
# 1.隊列為空,block為ture,會進入阻塞狀態,直到有新的值進入佇列
# 2.如果隊列為空.block為false,會彈出queue.empty()出錯
page = self.pagequeue.get(false)
url = "" + str(page) + "/"
content = requests.get(url,headers=self.headers).text
#呼叫資料佇列,將原始碼放進去
self.dataqueue.put(content)
except:
pass
print("結束"+self.threadname)
class threadparse(thread):
def __init__(self,threadname,dataqueue,filename,lock):
super(threadparse,self).__init__()
self.threadname = threadname
self.dataqueue = dataqueue
self.filename = filename
self.lock = lock
def run(self):
while not parse_exit:
try:
html = self.dataqueue.get(false)
self.parse(html)
except:
pass
def parse(self,html):
html = etree.html(html)
print(html)
# with 後面有兩個必須執行的操作:__enter__ 和 _exit__
# 不管裡面的操作結果如何,都會執行開啟、關閉
# 開啟鎖、處理內容、釋放鎖
with self.lock:
# 寫入儲存的解析後的資料
self.filename.write(json.dumps(html, ensure_ascii=false).encode("utf-8") + "\n")
crawl_exit = false
parse_exit = false
def main():
# 頁碼佇列,可以儲存20個值
pagequeue = queue(20)
# 放入1-10數字,先進先出
for i in range(1, 21):
pagequeue.put(i)
# 資料佇列,html原始碼,不寫引數,預設無限
dataqueue = queue()
# 建立鎖
lock = threading.lock()
# 採集執行緒名字
crawllist = ["採集執行緒1號", "採集執行緒2號", "採集執行緒3號"]
# 儲存採集執行緒
thread_crawl =
for threadname in crawllist:
# 寫乙個
thread = threadcrawl(threadname, pagequeue, dataqueue)
thread.start()
filename = open("duanzi.json","a")
#解析執行緒名字
parselist = ["解析執行緒1號","解析執行緒2號","解析執行緒3號"]
threadparse =
for threadname in parselist:
thread = threadparse(threadname,dataqueue,filename,lock)
thread.start()
#如果佇列不為空,一直在這等待
while not pagequeue.empty():
pass
#如果隊列為空,crawl_exit = true 退出
global crawl_exit
crawl_exit = true
#加阻塞,執行緒做完才能執行主線程
for thread in thread_crawl:
thread.join()
print(thread)
while not dataqueue.empty():
pass
global parse_exit
parse_exit = true
for thread in threadparse:
thread.join()
print(thread)
with lock:
# 關閉檔案
filename.close()
print("謝謝使用")
if __name__ == '__main__':
main()
多執行緒例子
coding utf 8 import threading import queue import time import random from faker import faker class mythread threading.thread 執行緒模型 def init self,queue...
POSIX執行緒多執行緒例子
include include include include define num threads 6 void thread function void arg int main sleep 1 printf waiting for threads to finish.n for lots of...
多執行緒的上手例子
溫習了下python的多執行緒,雖然python中的多執行緒是偽多執行緒,但是還是可以熟悉了解下。coding utf 8 created on 2017年8月17日 author zhouxuan import threading import time def aa print start aa...