Я хочу создать несколько файлов, используя несколько потоков, и добавить данные (после выполнения некоторой операции) в соответствующие файлы из соответствующих потоков.
Я пробовал, но данные путаются между потоками, а правильные данные не добавляются в соответствующие файлы.
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
with open('file_'+count+'_logs.txt', 'a+') as result:
result.write("Starting " + self.name)
result.write("Exiting " + self.name)
print ("Starting " + self.name)
print_time(self.name, self.counter, 5)
print ("Exiting " + self.name)
def print_time(threadName, delay, counter):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
myList = ['string0', 'string1', 'string2', 'string3']
if __name__ == "__main__":
count = 0
for data in myList:
count += 1
mythread = myThread(count, "Thread-" + str(count), count)
mythread.start()
mythread.join()
Я ожидаю, что 4 файла должны быть созданы из 4 потоков, а данные из потока 1 должны быть записаны в file_1_logs.txt и так далее... Но при записи данных иногда все данные записываются в один файл. Как правильно записать эти данные в файл?
count
существует в основном и является аргументом конструктора
Я знаю, но в нить не существует. Поток работает отдельно от основного. Не используйте глобальные переменные (или переменные более высокого уровня) при работе с потоками.
Что значит в нить?
Это ограничение, что я должен использовать переменные с более высокой областью видимости... Я получаю данные из другой функции, которая управляет моим потоком :(
Это ваш реальный код? Как написано, он даже не будет запускать потоки одновременно, поскольку вы join
каждый из них перед запуском следующего.
Нет.. это просто псевдокод. В реальном коде сначала запускаются все потоки, а затем присоединяются один за другим.
Пожалуйста, опубликуйте код, который действительно демонстрирует проблему. На первый взгляд, вам нужно использовать self.counter
в вашем методе run
вместо count
.
Если вы публикуете сокращенные примеры (что хорошо), убедитесь, что они ведут себя точно так же, как ваш реальный код, и раскрывают точно такую же проблему.
Не используйте в потоках переменные с более высокой областью действия или глобальные переменные. Каждая переменная (которую вы хотите изменить) должна быть локальной для потока.
Это означает, что вам нужно передать начальные значения всего в конструктор Thread. То же самое верно и для таких функций, как ваш print_time
. Либо все, что нужно функции для выполнения своей работы, передается через аргументы, либо вы превращаете это в метод класса.
Рассмотрим следующие изменения. Обратите внимание, что MyThread
полностью автономен:
from threading import Thread
from time import sleep
from datetime import datetime
class MyThread(Thread):
def __init__(self, threadID, name, delay, data):
Thread.__init__(self)
self.threadID = threadID
self.name = name
self.data = data
self.delay = delay
self.logfile = None
def run(self):
with open('file_%s_logs.txt' % self.threadID, 'a+') as logfile:
self.logfile = logfile
self.log("Starting")
self.print_time(5)
self.log("Exiting")
self.logfile = None
def print_time(self, repeat):
for c in range(repeat):
sleep(self.delay)
self.log(self.data)
def log(self, message):
now = datetime.now().isoformat()
formatted_line = "%s:%s:%s" % (now, self.name, message)
print(formatted_line)
if self.logfile:
self.logfile.write(formatted_line + '\n')
if __name__ == "__main__":
myList = ['string0', 'string1', 'string2', 'string3']
threads = []
# spawn threads
for idx, data in enumerate(myList):
thread = MyThread(idx, "Thread-%s" % idx, idx, data)
threads.append(thread)
thread.start()
# wait for threads to finish
while True:
if any(thread.is_alive() for thread in threads):
sleep(0.1)
else:
print("All done.")
break
Ваша переменная
count
не существует внутри потока. Может быть, вы имели в видуself.counter
?