日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Python3 多線程使用情況下詳解,代理IP訪問網(wǎng)站

系統(tǒng) 1805 0

Python3線程中常用的兩個(gè)模塊為**

_thread
threading(推薦使用)
每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口。但是線程不能夠獨(dú)立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制。

每個(gè)線程都有他自己的一組CPU寄存器,稱為線程的上下文,該上下文反映了線程上次運(yùn)行該線程的CPU寄存器的狀態(tài)。
thread 模塊已被廢棄。用戶可以使用 threading 模塊代替。所以,在 Python3 中不能再使用"thread" 模塊。為了兼容性,Python3 將 thread 重命名為 “_thread”。

_thread模塊

#Python中調(diào)用_thread模塊中的start_new_thread()函數(shù)產(chǎn)生新線程。_thread的語法如下:

            
               _thread.start_new._thread(function,args[,kwargs])

            
          

參數(shù)說明:
function - 線程函數(shù)。
args - 傳遞給線程函數(shù)的參數(shù),他必須是個(gè)tuple類型。
kwargs - 可選參數(shù)。
#_thread模塊除了產(chǎn)生線程外,還提供基本同步數(shù)據(jù)結(jié)構(gòu)鎖對(duì)象(lock object,也叫原語鎖、簡(jiǎn)單鎖、互斥鎖、互斥量、二值信號(hào)量)。同步原語與線程管理是密不可分的。

案例1

            
              import _thread
from time import sleep
from datetime import datetime

date_time_format='%y-%M-%d %H:%M:%S'
def date_time_str(date_time):
    return datetime.strftime(date_time,date_time_format)

def loop_one():
    print('+++線程一開始于:',date_time_str(datetime.now()))
    print('+++線程一休眠4秒')
    sleep(4)
    print('+++線程一休眠結(jié)束,結(jié)束于:',date_time_str(datetime.now()))

def loop_two():
    print('***線程二開始于:',date_time_str(datetime.now()))
    print('***線程二休眠2秒')
    sleep(2)
    print('***線程二結(jié)束休眠,結(jié)束于:',date_time_str(datetime.now()))

def main():
    print('-----所有線程開始時(shí)間:',date_time_str(datetime.now()))
    _thread.start_new_thread(loop_one,())
    _thread.start_new_thread(loop_two,())
    sleep(6)
    print('-----所有線程結(jié)束時(shí)間:',date_time_str(datetime.now()))

if __name__=='__main__':
    main()

            
          

案例2

            
              import _thread
import time

#為線程定義一個(gè)函數(shù)
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % ( threadName, time.ctime(time.time()) ))

#創(chuàng)建兩個(gè)線程
try:
   _thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   _thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print ("Error: 無法啟動(dòng)線程")
while 1:  
   pass

            
          

#執(zhí)行以上程后可以按下 ctrl-c to 退出。

#_thread模塊提供了簡(jiǎn)單的多線程機(jī)制,兩個(gè)循環(huán)并發(fā)執(zhí)行,總的運(yùn)行時(shí)間為最慢的線程的運(yùn)行時(shí)間(主線程6s),而不是所有線程的運(yùn)行時(shí)間之和。start_new_thread()要求至少傳兩個(gè)參數(shù),即使想要運(yùn)行的函數(shù)不要參數(shù),也要傳一個(gè)空元組。

#sleep(6)是讓主線程停下來。主線程一旦運(yùn)行結(jié)束,就關(guān)閉運(yùn)行著的其他兩個(gè)線程。這可能造成主線程過早或過晚退出,這時(shí)就要使用線程鎖,主線程可認(rèn)在兩個(gè)子線程都退出后立即退出。

            
              import _thread
from time import sleep
from datetime import datetime
loops=[4,2]
date_time_format='%y-%M-%d %H:%M:%S'

def date_time_str(date_time):
    return datetime.strftime(date_time,date_time_format)
def loop(n_loop,n_sec,lock):
    print('線程(',n_loop,')開始執(zhí)行:,date_time_str(datetime.now()),先休眠(',n_sec,')秒')
    sleep(n_sec)
    print('線程(',n_loop,')休眠結(jié)束,結(jié)束于:',date_time_str(datetime.now()))
    lock.release()
def main():
    print('---所有線程開始執(zhí)行...')
    locks=[]
    n_loops=range(len(loops))
    for i in n_loops:
        lock=_thread.allocate_lock()
        lock.acquire()
        locks.append(lock)
    for i in n_loops:
        _thread.start_new_thread(loop,(i,loops[i],locks[i]))

    for i in n_loops:
        while locks[i].locked():
            pass

    print('---所有線程執(zhí)行結(jié)束:',date_time_str(datetime.now()))

if __name__=='__main__':
    main()

            
          

線程模塊

Python3 通過兩個(gè)標(biāo)準(zhǔn)庫 _thread 和 threading 提供對(duì)線程的支持。

_thread 提供了低級(jí)別的、原始的線程以及一個(gè)簡(jiǎn)單的鎖,它相比于 threading 模塊的功能還是比較有限的。

threading 模塊除了包含 _thread 模塊中的所有方法外,還提供的其他方法:

threading.currentThread(): 返回當(dāng)前的線程變量。
threading.enumerate(): 返回一個(gè)包含正在運(yùn)行的線程的list。正在運(yùn)行指線程啟動(dòng)后、結(jié)束前,不包括啟動(dòng)前和終止后的線程。
threading.activeCount(): 返回正在運(yùn)行的線程數(shù)量,與len(threading.enumerate())有相同的結(jié)果。
除了使用方法外,線程模塊同樣提供了Thread類來處理線程,Thread類提供了以下方法:

run(): 用以表示線程活動(dòng)的方法。
start():啟動(dòng)線程活動(dòng)。
join([time]): 等待至線程中止。這阻塞調(diào)用線程直至線程的join() 方法被調(diào)用中止-正常退出或者拋出未處理的異常-或者是可選的超時(shí)發(fā)生。
isAlive(): 返回線程是否活動(dòng)的。
getName(): 返回線程名。
setName(): 設(shè)置線程名。

使用 threading 模塊創(chuàng)建線程

我們可以通過直接從 threading.Thread 繼承創(chuàng)建一個(gè)新的子類,并實(shí)例化后調(diào)用 start() 方法啟動(dòng)新線程,即它調(diào)用了線程的 run() 方法:

            
              import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("開始線程:" + self.name)
        print_time(self.name, self.counter, 5)
        print ("退出線程:" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# 創(chuàng)建新線程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 開啟新線程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主線程")

            
          

線程同步

如果多個(gè)線程共同對(duì)某個(gè)數(shù)據(jù)修改,則可能出現(xiàn)不可預(yù)料的結(jié)果,為了保證數(shù)據(jù)的正確性,需要對(duì)多個(gè)線程進(jìn)行同步。

使用 Thread 對(duì)象的 Lock 和 Rlock 可以實(shí)現(xiàn)簡(jiǎn)單的線程同步,這兩個(gè)對(duì)象都有 acquire 方法和 release 方法,對(duì)于那些需要每次只允許一個(gè)線程操作的數(shù)據(jù),可以將其操作放到 acquire 和 release 方法之間。如下:

多線程的優(yōu)勢(shì)在于可以同時(shí)運(yùn)行多個(gè)任務(wù)(至少感覺起來是這樣)。但是當(dāng)線程需要共享數(shù)據(jù)時(shí),可能存在數(shù)據(jù)不同步的問題。

考慮這樣一種情況:一個(gè)列表里所有元素都是0,線程"set"從后向前把所有元素改成1,而線程"print"負(fù)責(zé)從前往后讀取列表并打印。

那么,可能線程"set"開始改的時(shí)候,線程"print"便來打印列表了,輸出就成了一半0一半1,這就是數(shù)據(jù)的不同步。為了避免這種情況,引入了鎖的概念。

鎖有兩種狀態(tài)——鎖定和未鎖定。每當(dāng)一個(gè)線程比如"set"要訪問共享數(shù)據(jù)時(shí),必須先獲得鎖定;如果已經(jīng)有別的線程比如"print"獲得鎖定了,那么就讓線程"set"暫停,也就是同步阻塞;等到線程"print"訪問完畢,釋放鎖以后,再讓線程"set"繼續(xù)。

經(jīng)過這樣的處理,打印列表時(shí)要么全部輸出0,要么全部輸出1,不會(huì)再出現(xiàn)一半0一半1的尷尬場(chǎng)面。
實(shí)例:

            
              import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("開啟線程: " + self.name)
        # 獲取鎖,用于線程同步
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 釋放鎖,開啟下一個(gè)線程
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 創(chuàng)建新線程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 開啟新線程
thread1.start()
thread2.start()

# 添加線程到線程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有線程完成
for t in threads:
    t.join()
print ("退出主線程")

            
          

線程優(yōu)先級(jí)隊(duì)列( Queue)

Python 的 Queue 模塊中提供了同步的、線程安全的隊(duì)列類,包括FIFO(先入先出)隊(duì)列Queue,LIFO(后入先出)隊(duì)列LifoQueue,和優(yōu)先級(jí)隊(duì)列 PriorityQueue。

這些隊(duì)列都實(shí)現(xiàn)了鎖原語,能夠在多線程中直接使用,可以使用隊(duì)列來實(shí)現(xiàn)線程間的同步。

Queue 模塊中的常用方法:

Queue.qsize() 返回隊(duì)列的大小
Queue.empty() 如果隊(duì)列為空,返回True,反之False
Queue.full() 如果隊(duì)列滿了,返回True,反之False
Queue.full 與 maxsize 大小對(duì)應(yīng)
Queue.get([block[, timeout]])獲取隊(duì)列,timeout等待時(shí)間
Queue.get_nowait() 相當(dāng)Queue.get(False)
Queue.put(item) 寫入隊(duì)列,timeout等待時(shí)間
Queue.put_nowait(item) 相當(dāng)Queue.put(item, False)
Queue.task_done() 在完成一項(xiàng)工作之后,Queue.task_done()函數(shù)向任務(wù)已經(jīng)完成的隊(duì)列發(fā)送一個(gè)信號(hào)
Queue.join() 實(shí)際上意味著等到隊(duì)列為空,再執(zhí)行別的操作

            
              import queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print ("開啟線程:" + self.name)
        process_data(self.name, self.q)
        print ("退出線程:" + self.name)

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print ("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1

#創(chuàng)建新線程
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

#填充隊(duì)列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

#等待隊(duì)列清空
while not workQueue.empty():
    pass

#通知線程是時(shí)候退出
exitFlag = 1

#等待所有線程完成
for t in threads:
    t.join()
print ("退出主線程")

            
          

python之多線程

https://www.cnblogs.com/smallmars/p/7149507.html

            
              #coding=utf-8
import threading  # 導(dǎo)入threading包
from time import sleep
import time

def task1():
    print("Task 1 executed.")
    sleep(1)

def task2():
    print("Task 2 executed.")
    sleep(5)

print("多線程:")
starttime = time.time();  # 記錄開始時(shí)間
threads = []  # 創(chuàng)建一個(gè)線程列表,用于存放需要執(zhí)行的子線程
t1 = threading.Thread(target=task1)  # 創(chuàng)建第一個(gè)子線程,子線程的任務(wù)是調(diào)用task1函數(shù),注意函數(shù)名后不能有()
threads.append(t1)  # 將這個(gè)子線程添加到線程列表中
t2 = threading.Thread(target=task2)  # 創(chuàng)建第二個(gè)子線程
threads.append(t2)  # 將這個(gè)子線程添加到線程列表中

for t in threads:  # 遍歷線程列表
    t.setDaemon(True)  # 將線程聲明為守護(hù)線程,必須在start() 方法調(diào)用之前設(shè)置,如果不設(shè)置為守護(hù)線程程序會(huì)被無限掛起
    t.start()  # 啟動(dòng)子線程
endtime = time.time();  # 記錄程序結(jié)束時(shí)間
totaltime = endtime - starttime;  # 計(jì)算程序執(zhí)行耗時(shí)
print("耗時(shí):{0:.5f}秒".format(totaltime));  # 格式輸出耗時(shí)
print('---------------------------')

#以下為普通的單線程執(zhí)行過程,不需解釋
print("單線程:")
starttime = time.time();
task1();
task2();
endtime = time.time();
totaltime = endtime - starttime;
print("耗時(shí):{0:.5f}秒".format(totaltime));


            
          

偽裝好了才能出發(fā),通過proxy代理IP訪問網(wǎng)站,python爬蟲(1)

            
              from urllib.request import Request, build_opener
from fake_useragent import UserAgent
from urllib.request import ProxyHandler
url = "http://httpbin.org/get"
headers={
 "User-Agent": UserAgent().chrome
}
request = Request(url, headers=headers)
handler = ProxyHandler({"http" : "112.85.129.8:9999"})
opener = build_opener(handler)
response = opener.open(request)
print(response.read().decode())


            
          

通過ajax請(qǐng)求獲得信息,沒想到應(yīng)用范圍如此廣,python爬蟲(2)

            
              from urllib.request import Request, urlopen
from fake_useragent import UserAgent
base_url ="https://movie.douban.com/j/search_subjects?type=tv&tag=%E7%83%AD%E9%97%A8&page_limit=50&page_start={}"
i = 0
while True:
 headers = {
 "User-Agent": UserAgent().chrome
 }
 url = base_url.format(i * 20)
 request = Request(url, headers=headers)
 response = urlopen(request)
 info = response.read().decode()
 print(info)
 if info == "" or info is None or i==10:
 print("got all of data")
 break
 i += 1
 print("get "+ str(i) + " page")

            
          

3分鐘搞定一個(gè)爬蟲,貼吧爬蟲就是這么簡(jiǎn)單,python爬蟲(3)

            
              from urllib.request import Request, urlopen
from urllib.parse import urlencode
from fake_useragent import UserAgent
def get_html(url):
 headers = {
 "User-Agent": UserAgent().chrome
 }
 request =Request(url, headers=headers)
 response = urlopen(request)
 print(response.read().decode())
 return response.read()
def save_html(filename, html_bytes):
 with open(filename, "wb" ) as f:
 f.write(html_bytes)
def main():
 content = input("下載內(nèi)容:")
 number = input("下載頁面:")
 base_url = "https://tieba.baidu.com/f?ie=utf-8&{}"
 for pn in range(int(number)):
 args = {
 "pn": pn*50,
 "kw": content
 }
 args = urlencode(args)
 filename = "第" + str(pn) + "頁.html"
 print("正在下載"+filename)
 html_bytes = get_html(base_url.format(args))
 save_html(filename, html_bytes)
if __name__ == '__main__':
 main()

            
          

request請(qǐng)求中進(jìn)行url轉(zhuǎn)碼,結(jié)果意想不到,python爬蟲(4)

            
              from urllib.request import Request, urlopen
from urllib.parse import urlencode
parameters={"wd":"你好"}
url = "https://www.baidu.com/s?wd={}".format(urlencode(parameters))
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"}
request = Request(url, headers=headers)
response = urlopen(request)
print(response.read().decode())

            
          

閑著會(huì)生病的,玩玩python吧,python爬蟲(5)

            
              from urllib.request import urlopen
from urllib.request import Request
from random import choice
url = "http://www.baidu.com"
user_agents = [
"Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0",
"Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"]
headers = {"User-Agent": choice(user_agents)}
request = Request(url, headers=headers)
print(request.get_header('User-agent'))
response = urlopen(request)
info = response.read()
#print(info)

            
          

更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 大同市| 白水县| 洛浦县| 台州市| 历史| 北安市| 闸北区| 冷水江市| 古蔺县| 伊通| 霍城县| 师宗县| 昌宁县| 安丘市| 芮城县| 陵川县| 呈贡县| 织金县| 东安县| 天台县| 扶风县| 泸州市| 彰武县| 乌兰县| 松溪县| 革吉县| 鱼台县| 久治县| 长乐市| 柳江县| 女性| 乌拉特前旗| 石城县| 永修县| 二连浩特市| 内黄县| 济南市| 玉屏| 邮箱| 南宁市| 固始县|