Потоки Tcl не обмениваются данными (если вы явно не используете определенные средства из пакета Thread) и вместо этого обмениваются данными через передачу сообщений.Таким образом, похоже, что можно пойти путем установки отдельного потока «logger» и просто поставить в очередь сообщения о регистрации в нем из рабочих потоков.
В противном случае точка разногласия, вероятно, будет где-то в используемом ресурсе ОС.регистратором для фактической записи данных.
Обновление Хорошо, вот рабочий набросок того, что я фактически предложил реализовать:
package require Tcl 8.5
package require Thread
proc make_worker_thread {logger_id body} {
set newbody [list set ::logger $logger_id]
append newbody \n {
proc ::log {severity msg} {
global logger
thread::send $logger [list ::log $severity $msg]
}
} \n $body
thread::create $newbody
}
set logger [thread::create {
package require logger
proc log {severity msg} {
puts "hey, that's it: ($severity) $msg"
}
puts "logger thread created: [thread::id]"
thread::wait
}]
for {set i 0} {$i < 3} {incr i} {
make_worker_thread $logger {
proc post_msg {} {
log notice "A message from [thread::id]"
after 1000 ::post_msg
}
puts "worker thread created: [thread::id]"
after 1000 ::post_msg
thread::wait
}
}
vwait forever
Этот код создает один поток регистратораи четыре рабочих потока, каждый из которых отправляет сообщение в логгер один раз в секунду.Код работает до тех пор, пока не будет прерван вручную.Поток логгера просто-напросто выводит сообщение о том, что он был передан на консоль, но, как уже упоминал кто-то из этого потока, вы, возможно, могли бы использовать пакет «logger» из Tcllib, если вам нужны такие причудливые вещи, как средства.
Чтобы повторить мои замечания:
- Сам пакет логгера, по-видимому, ничего не знает о многопоточности.
- Потоки Tcl хорошо разделены и обычно обмениваются сообщениями.
- Следовательно, создайте поток для регистратора и научите рабочие потоки отправлять ему сообщения;поэтому рабочие потоки не имеют отношения к тому, как реализован регистратор.
PS В рабочих потоках вы можете использовать [thread::send -async ...]
, чтобы сделать отправку сообщений журнала полностью асинхронной.