Предотвратить блокировку потока tcl главным циклом событий - PullRequest
1 голос
/ 19 ноября 2010

Я пытаюсь запустить поток непрерывно, и он не будет заблокирован циклом основного события tcl. Вот простой пример того, что я пытаюсь сделать:

#!/bin/sh
#\
exec tclsh "$0" "$@"

package require Thread

set ::a_thread [thread::create {thread::wait}]

proc start_a {} {
  thread::send $::a_thread {
    puts "Running a thread"
  }
  after 1000 a_start
}

proc infinite_loop {} {
  while {1} {
    puts "Loop"
    after 500
  }
}

start_a
infinite_loop

vwait forever

В этом коде вызывается процесс infinite_loop, и цикл основного события выполняется бесконечно. Я хотел бы, чтобы a_thread все еще мог работать в фоновом режиме, хотя. Как мне этого добиться?

Ответы [ 2 ]

6 голосов
/ 19 ноября 2010

Основной цикл событий не блокирует ваш поток.Вместо этого вы используете основной цикл событий для планирования сценариев, выполняемых в потоке.Вместо этого запустите планировщик в самом потоке:

Код протестирован и работает как ожидалось:

thread::send $::a_thread {
    proc loop {} {
        puts "running a thread"
        after 1000 loop
    }
    loop
}

while 1 {
    puts "loop"
    after 500
}
5 голосов
/ 19 ноября 2010

Ответ, конечно, тот, который дал Slebetman.Тем не менее, один из способов отладки такого рода вещей (особенно в более сложных случаях) заключается в добавлении префикса к сообщениям, напечатанным каждым потоком, по результату thread::id, и к убедитесь, что Вы печатаете сообщение при начале каждого цикла.Например:

package require Thread

set ::a_thread [thread::create {thread::wait}]

proc start_a {} {
  puts "[thread::id]: Dispatch to $::a_thread"
  thread::send $::a_thread {
    puts "[thread::id]: Running a thread"
  }
  after 1000 a_start
}

proc infinite_loop {} {
  while {1} {
    puts "[thread::id]: Loop"
    after 500
  }
}

start_a
infinite_loop
puts "[thread::id]: Start main event loop"
vwait forever

Это бы указывало на то, что отправка происходила один раз, что запуск в другом потоке происходит синхронно (thread::send ожидает завершения выполнения сценария по умолчанию), ичто бесконечный цикл предотвращает запуск основного цикла событий (и, следовательно, повторное планирование диспетчеризации).Поскольку вы не знали, кто чем занимается, конечно же, была путаница!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...