簡體   English   中英

訪問同一對象時,Python線程和全局解釋器鎖定

[英]Python thread and global interpreter lock when access same object

我試圖了解python線程及其工作方式。

據我了解,我知道有GIL(全局解釋器鎖)可以防止兩個線程同時訪問內存。

即使它會使程序變慢,這也很合理。

但是下面的代碼顯示了意外的結果。

import thread, time
mylist = [[0,1]]

def listTo300Elem(id):
    while len(mylist) < 300:
        mylist.append([id, mylist[-1][1]+1])

thread.start_new_thread(listTo300Elem, (1,))
thread.start_new_thread(listTo300Elem, (2,))
thread.start_new_thread(listTo300Elem, (3,))
thread.start_new_thread(listTo300Elem, (4,))
thread.start_new_thread(listTo300Elem, (5,))
thread.start_new_thread(listTo300Elem, (6,))
thread.start_new_thread(listTo300Elem, (7,))

time.sleep(5)

print mylist
print len(mylist)

結果是

[[0,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[ 1,9],[1,10],[1,11],[1,12],[1,13],[1,14],[1,15],[1,16],[1, 17],[1、18],[1、19],[1、20],[1、21],[1、22],[1、23],[1、24],[1、25] ,[1、26],[1、27],[1、28],[1、29],[1、30],[1、31],[1、32],[1、33],[ 1,34],[1,35],[1,36],[1,37],[1,38],[1,39],[1,40],[1,41],[1, 42],[1、43],[1、44],[1、45],[1、46],[1、47],[1、48],[1、49],[1、50] ,[1、51],[1、52],[1、53],[1、54],[1、55],[1、56],[1、57],[1、58],[ 1,59],[1,60],[1,61],[1,62],[1,63],[1,64],[1,65],[1,66],[1, 67],[1、68],[1、69],[1、70],[1、71],[1、72],[2、73],[2、74],[2、75] ,[2、76],[2、77],[2、78],[2、79],[5、80],[5、81],[5、82],[5、83],[ 5,84],[5,85],[5,86],[5,87],[5,88],[5,89],[5,90],[5,91],[5, 92],[5、93],[5、94],[3、95],[3、96],[3、97],[3、98],[3、99],[3、100] ,[3、101],[3、102],[3、103],[3、104],[3、105],[3、106],[3、107],[3、108],[ 3,109],[3,110],[3,111 ],[3、112],[3、113],[3、114],[3、115],[3、116],[3、117],[7、118],[7、119], [7,120],[7,121],[7,122],[7,123],[7,124],[2,80],[2,81],[2,82],[2 ,83],[2,84],[2,85],[2,86],[2,87],[2,88],[2,89],[2,90],[2,91 ],[2、92],[2、93],[2、94],[2、95],[2、96],[2、97],[2、98],[2、99], [2,100],[2,101],[2,102],[2,103],[2,104],[2,105],[2,106],[2,107],[2 ,108],[2、109],[2、110],[2、111],[2、112],[2、113],[2、114],[2、115],[2、116 ],[2、117],[2、118],[2、119],[2、120],[2、121],[2、122],[2、123],[2、124], [2,125],[2,126],[2,127],[2,128],[2,129],[2,130],[2,131],[2,132],[2 ,133],[2、134],[2、135],[2、136],[2、137],[2、138],[2、139],[2、140],[2、141] ],[7、125],[7、126],[7、127],[7、128],[7、129],[7、130],[7、131],[7、132], [7,133],[7,134],[7,135],[7,136],[7,137],[7,138],[7,139],[7,140],[7 ,141],[7,142],[7,143],[7,144],[7,145],[7,146],[7,147],[7,148],[7,149] ],[7、150],[7、151 ],[7、152],[7、153],[7、154],[7、155],[7、156],[7、157],[7、158],[7、159], [7,160],[7,161],[7,162],[7,163],[7,164],[7,165],[7,166],[7,167],[7 ,168],[7,169],[7,170],[7,171],[6,172],[6,173],[6,174],[6,175],[6,176] ],[6、177],[6、178],[3、179],[3、180],[3、181],[3、182],[3、183],[3、184], [3,185],[3,186],[3,187],[3,188],[3,189],[3,190],[3,191],[3,192],[3 ,193],[3,194],[3,195],[3,196],[3,197],[3,198],[3,199],[3,200],[3,201] ],[7、202],[7、203],[7、204],[7、205],[7、206],[7、207],[7、208],[7、209], [1、210],[1、211],[1、212],[1、213],[1、214],[1、215],[1、216],[1、217],[1 ,218],[1、219],[1、220],[1、221],[1、222],[1、223],[1、224],[1、225],[1、226] ],[1、227],[1、228],[1、229],[1、230],[1、231],[1、232],[1、233],[1、234], [1、235],[1、236],[1、237],[1、238],[3、239],[5、240],[2、142],[6、179]] 304

據我了解,由於GIL,結果必須是有序的,但事實並非如此。

我可以得到此示例的說明以及要研究的其他項目嗎?

您期望什么? 那個線程添加一個項目,之后另一個線程等等? 比起為什么這么多線程,如果一次只能工作一個線程呢? 線程試圖同時處理一個對象。 但是由於GIL對並行計算不是一件好事,所以它們做起來很難看。

為了更了解GIL的工作原理,您可以添加日志記錄。

logging.basicConfig(format="%(levelname)-8s [%(asctime)s] %(threadName)-12s %(message)s", level=logging.DEBUG, filename='log.log')

def listTo300Elem(id):
    list_len = len(mylist)
    while list_len < 300:
        item = mylist[-1][1]+1]
        mylist.append([id, item])
        logging.debug('Len = {}, item {} added'.format(list_len, item))
        list_len = len(mylist)
    logging.debug('Len = {}, exit'.format(list_len, item))

因此,python線程並不適合所有情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM