访问同一对象

时间:2017-12-14 06:39:18

标签: python multithreading gil

我正在尝试理解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,11],[2,113],[2,111],[2,111],[2, 116],[2,111],[2,118],[2,111],[2,120],[2,121],[2,122],[2,123],[2,124] ,[2,125],[2,126],[2,127],[2,128],[2,129],[2,130],[2,113],[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,结果必须按顺序排列,但它们不是。

我是否可以获得此示例的解释以及需要研究的其他项目?

1 个答案:

答案 0 :(得分:0)

你期待什么?那一个线程添加一个项目,之后另一个线程等?为什么这么多线程,如果他们一次工作?线程正在尝试与一个对象同时工作。但是由于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中的线程并不适合所有情况。