我测试了我的代码输出并对其进行了排序,但我没有按预期获得 0-1999,缺少行。我的代码线程不安全吗?请建议如何在我的代码中添加线程锁,我发现我的 except all 不会引发任何错误,这是正确的吗?谢谢
import time, threading, random
class MyThreadWithArgs(threading.Thread):
def __init__(self, string):
threading.Thread.__init__(self)
self.string = string
def run(self):
try:
fo = open("foo.np2", "a")
fo.write( self.string )
fo.write( '\n' )
time.sleep(random.uniform(0.1, 0.9))
fo.close()
except:
print ("error logging " + self.string)
ttl_threads = 2000
for i in range(ttl_threads):
t = MyThreadWithArgs(string = str(i))
t.start()
最佳答案
这可能会按预期工作。为了简单起见,删除了异常处理。
import time, threading, random
class MyThreadWithArgs(threading.Thread):
def __init__(self, string):
threading.Thread.__init__(self)
self.string = string
def run(self):
fo.write( self.string + '\n' )
time.sleep(random.uniform(0.1, 0.9))
fo = open("foo.np2", "a")
ttl_threads = 2000
for i in range(ttl_threads):
t = MyThreadWithArgs(string = str(i))
t.start()
在原始程序中,您以附加模式打开同一文件的多个句柄。每个句柄都维护自己的指针,指向它认为的文件末尾,但线程 0 可以在线程 1 写入之前修改文件。 thread-1 仍会写入调用 open 时文件结尾 WAS 的位置。
通过仅保持一个文件描述符打开,您只有一个文件结束指针和底层的 write
系统调用可能可以通过操作系统内部锁定机制在给定的文件描述符上重入。
我所做的另一个更改是将两次调用中的字符串连接到 write()
因为作为两个单独的调用,您为调度提供了在系统调用之间切换线程的机会,并且可能最终得到两个 self.string
连续的值后跟两个或多个 \n
连续的字符串。
我不知道我的什么(如果有的话)可以保证 python 的 write
,我只是按照我所知道的方式<unistd.h> write()
在大多数 POSIX 平台上以 C 语言工作。如果你想要保证,请检查 python 文档,或将 write()
括起来带锁调用。
关于在线程中写入的python文件不写入所有行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28411040/