繁体   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