Вы столкнулись с известной проблемой о том, что текущая реализация данных привязки Event Hub пропустила некоторые свойства, такие как идентификатор устройства, который вы ищете.
В нашем связывании мы приняли это изменение, выведя только 4 свойства верхнего уровня этого типа, не осознавая, что оно происходит из словаря. Таким образом, код, в котором мы заполняем данные привязки здесь , является ошибкой. Вместо нашей собственной реализации ToDictionary здесь для этих 4 свойств (которая отфильтровывает другие системные свойства), мы должны просто добавить всю коллекцию, которая уже является словарем.
blockquote>
Создайте блокировку вне метода.
class Agent(Thread):
mylock = Lock()
def write_result(self):
self.mylock.acquire()
try:
...
finally:
self.mylock.release()
или при использовании Python> = 2.5:
class Agent(Thread):
mylock = Lock()
def write_result(self):
with self.mylock:
...
Для использования этого с python 2.5, необходимо импортировать оператор из будущего:
from __future__ import with_statement
Для Вашего варианта использования один подход мог быть должен записать a file
подкласс, который блокирует:
class LockedWrite(file):
""" Wrapper class to a file object that locks writes """
def __init__(self, *args, **kwds):
super(LockedWrite, self).__init__(*args, **kwds)
self._lock = Lock()
def write(self, *args, **kwds):
self._lock.acquire()
try:
super(LockedWrite, self).write(*args, **kwds)
finally:
self._lock.release()
Для использования в коде просто заменяют следующие функции:
def main():
f = LockedWrite('foo.txt', 'a')
for i in range(20):
agent = Agent(i, f)
agent.start()
class Agent(Thread):
def __init__(self, thread_num, fileobj):
Thread.__init__(self)
self.thread_num = thread_num
self._file = fileobj
# ...
def write_result(self):
self._file.write('hello from thread %s\n' % self.thread_num)
Этот подход помещает захват файла в сам файл, который кажется инструментом для очистки, по моему скромному мнению,
Блокировка () метод возвращает объект блокирования для каждого вызова. Таким образом, каждый поток (на самом деле каждый вызов к write_result) будет иметь различный объект блокирования. И не будет никакой блокировки.
Блокировка это использовало потребности быть характерным для всех потоков или по крайней мере гарантировать, что две блокировки не могут заблокировать тот же ресурс одновременно.
Можно упростить вещи немного (за счет немного больше служебного) путем называния единственного потока (вероятно, созданным исключительно с этой целью) как единственный поток, который пишет в файл, и имейте всего другого делегата потоков в устройстве записи файла путем размещения строки, которую они хотят добавить к файлу в a queue.Queue
объект.
У очередей есть вся встроенная блокировка, таким образом, любой поток может безопасно звонить Queue.put()
в любое время. Устройство записи файла было бы единственным вызовом потока Queue.get()
, и может, по-видимому, провести большую часть его времени, блокируясь на том вызове (с разумным тайм-аутом, чтобы позволить потоку чисто отвечать на запрос завершения работы). Все проблемы синхронизации будут обработаны Очередью, и Вы будете сэкономлены, имея необходимость волноваться о том, забыли ли Вы, что некоторая блокировка получает/выпускает где-нибудь... :)
Я вполне уверен, что блокировка должна быть тем же объектом для каждого потока. Попробуйте это:
import time
from threading import Thread, Lock
def main():
lock = Lock()
for i in range(20):
agent = Agent(i, lock)
agent.start()
class Agent(Thread, Lock):
def __init__(self, thread_num, lock):
Thread.__init__(self)
self.thread_num = thread_num
self.lock = lock
def run(self):
while True:
print 'hello from thread %s' % self.thread_num
self.write_result()
def write_result(self):
self.lock.acquire()
try:
f = open('foo.txt', 'a')
f.write('hello from thread %s\n' % self.thread_num)
f.flush()
f.close()
finally:
lock.release()
if __name__ == '__main__':
main()
Экземпляр блокировки должен быть связан с экземпляром файла.
Другими словами, необходимо создать и блокировку и файл одновременно и передать обоих каждому потоку.