Как убить поток из другого потока в вала

У меня есть основной поток, который создает другой поток для выполнения некоторой работы. основной поток имеет ссылку на этот поток. Как через некоторое время принудительно убить этот поток, даже если поток все еще работает. Я не могу найти правильный вызов функции, который делает это.

любая помощь будет ощутимой.

Исходная проблема, которую я хочу решить, заключается в том, что я создал поток для выполнения операции с привязкой к ЦП, которая может занять 1 секунду или может занять 10 часов. Я не могу предсказать, сколько времени это займет. Если это занимает слишком много времени, я хочу, чтобы он изящно отказался от работы, когда/если я захочу. я могу как-то передать это сообщение в эту ветку??


person imagin    schedule 25.04.2013    source источник
comment
Почему вы хотите убить тред? Что вы действительно пытаетесь сделать?   -  person razeh    schedule 25.04.2013
comment
Я отредактировал постановку задачи, чтобы объяснить, что я хочу сделать   -  person imagin    schedule 25.04.2013
comment
Помимо утечки памяти, вы оставляете много данных в неизвестном состоянии. вряд ли это хорошая идея. Подайте сигнал потоку об остановке и проверьте наличие запроса на остановку.   -  person Emond Erno    schedule 25.04.2013


Ответы (1)


Предполагая, что вы говорите о GLib.Thread, вы не можете. Даже если бы вы могли, вы, вероятно, не захотели бы, так как вы, вероятно, в конечном итоге утечете значительный объем памяти.

То, что вы должны сделать, это запросить, чтобы поток убил себя. Обычно это делается с помощью переменной, указывающей, был ли запрошен останов операции при первой же возможности. GLib.Cancellable разработан для этой цели и интегрируется с операциями ввода-вывода в GIO.

Пример:

private static int main (string[] args) {
  GLib.Cancellable cancellable = new GLib.Cancellable ();
  new GLib.Thread<int> (null, () => {
      try {
        for ( int i = 0 ; i < 16 ; i++ ) {
          cancellable.set_error_if_cancelled ();
          GLib.debug ("%d", i);
          GLib.Thread.usleep ((ulong) GLib.TimeSpan.MILLISECOND * 100);
        }

        return 0;
      } catch ( GLib.Error e ) {
        GLib.warning (e.message);
        return -1;
      }
    });

  GLib.Thread.usleep ((ulong) GLib.TimeSpan.SECOND);
  cancellable.cancel ();

  /* Make sure the thread has some time to cancel.  In an application
   * with a UI you probably wouldn't need to do this artificially,
   * since the entire application probably wouldn't exit immediately
   * after cancelling the thread (otherwise why bother cancelling the
   * thread?  Just exit the program) */
  GLib.Thread.usleep ((ulong) GLib.TimeSpan.MILLISECOND * 150);

  return 0;
}
person nemequ    schedule 25.04.2013
comment
здесь мы должны проверить cancellable.set_error_if_cancelled() в каждом цикле, чтобы проверить, не был ли он уже отменен, могу ли я сделать что-то только в начале нового потока, чтобы убедиться, что он будет завершен при отмене, потому что задание, которое выполняет новый поток не имеет такого типа простых циклов, где я могу это проверить. Я не могу проверить это условие просто после каждого значимого блока кода. - person imagin; 26.04.2013
comment
Нет. Почему бы вам не проверить это после каждого осмысленного блока кода? Вы просто передаете отмену любым методам, которые вы вызываете из обратного вызова потока, и заставляете их генерировать исключения. Тогда все, что вам нужно сделать, это случайный вызов метода cancellable.set_error_if_cancelled(), что не так уж сложно. - person nemequ; 26.04.2013
comment
Возможно, вы задаете неправильный вопрос. Вместо того, чтобы спрашивать, как убить поток (с бойкими потоками, как я уже сказал, вы не можете), возможно, вам следует спросить, как сделать длительную операцию с интенсивным использованием ЦП, для которой вы не можете (или не хотите) t) изменить код, отменить... В этом случае ответом будет использование процесса, а не потока. - person nemequ; 26.04.2013