我测试了我的代码输出并对其进行了排序,但我没有像预期的那样得到 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 开始写入之前修改文件。线程 1 在调用打开时仍将写入文件结尾 WAS 的位置。
通过仅保持一个文件描述符打开,您只有一个文件结束指针和底层 write
系统调用可能通过操作系统内部锁定机制在给定的文件描述符上可重入。
我所做的另一项更改是将两次调用中的字符串连接起来 write()
因为作为两个单独的调用,您让调度有机会在系统调用之间切换线程,并且很可能以两个 self.string
结束。一行中的值后跟两个或更多 \n
连续的字符串。
我不知道我的什么(如果有的话)保证 python 关于 write
,我只是说说我所知道的 <unistd.h> write()
在大多数 POSIX 平台上使用 C 语言工作。如果您想要保证,请查看 python 文档,或将 write()
括起来带锁调用。
我是一名优秀的程序员,十分优秀!