这是一个线程安全的模块,实际上你是如何编写的?

时间:2012-05-12 18:30:47

标签: python multithreading

我实际上正在使用涉及大量mysql操作的多线程程序,基本上它非常麻烦,因为你必须想出一种智能方法来使所有查询都能正常工作。这让我想到如何使模块线程安全。

无论如何,我试图以这种方式提出我的问题:假设您需要不断地将新内容添加到包含许多不同线程的txt文件中,main.py肯定会如下所示:

import threading

lock = threading.RLock()

def AppendStr(the_str):
    write_thread = threading.Thread(target = RealAppending, args = (the_str, ))
    write_thread.start()

def RealAppending(the_str):
    lock.acquire()

    the_file = open("test.txt", "a")
    the_file.append(the_str)
    the_file.close()

    lock.release()

def WorkerThread(some_arg):
    do stuff

    AppendStr("whatever you like")

for counter in range(100):
    new_thread = threading.Thread(target = WorkerThread, args = (some_arg, ))
    new_thread.start()

嗯,问题是,如果我正在尝试使代码整洁且易于维护,如果我将下面的代码放入 write.py中它仍然有效:

import threading

lock = threading.RLock()

def AppendStr(the_str):
    write_thread = threading.Thread(target = RealAppending, args = (the_str, ))
    write_thread.start()

def RealAppending(the_str):
    lock.acquire()

    the_file = open("test.txt", "a")
    the_file.append(the_str)
    the_file.close()

    lock.release()

并在 main.py中执行此操作:(我真的不明白import如何在python中运行)

import write

def WorkerThread(some_arg):
    do stuff

    write.AppendStr("whatever you like")

for counter in range(100):
    new_thread = threading.Thread(target = WorkerThread, args = (some_arg, ))
    new_thread.start()

如果有许多其他模块以多线程方式使用write.py,然后您在main.py中导入这些模块并从那里调用不同的def,那该怎么办呢?一切都会按预期运作吗?如果没有,我该怎么做才能设计一个可以像这样使用的终极线程安全模块?

如果您在许多其他模块中导入write.py,它们是否共享相同的lock?这些模块中的变量范围是什么?

1 个答案:

答案 0 :(得分:0)

这看起来像一个线程模块,但有错误:

这是一个更好的版本:

def RealAppending(the_str):
    lock.acquire()
    try:
        the_file = open("test.txt", "a")
        try:
            the_file.write(the_str) # write
        finally:
            the_file.close()
    finally: # if an error occurs
        lock.release()

,因为:

  • 如果在写入文件时发生错误,则必须释放锁

上面的语法适用于python 2.3及更低版本

这是完全相同的改进版本:

def RealAppending(the_str):
    with lock:
        with open("test.txt", "a") as the_file:
            the_file.write(the_str) # write

所以是的,你的模块是线程。 可以添加一些内容以防止用户以非线程方式使用它:

# write.py
__all__ = ['AppendStr'] # put all functions in except the ones others shall not see
# so id you do from write import * nothing else will be imported but what is __all__

但是你仍然无法知道将字符串写入文件的顺序。