Как убить конкретный поток из массива потоков

2

Я создаю массив потоков на основе количества записей в базе данных. Затем каждый поток опроса ipaddress и затем спит какое-то время, а затем снова repolls. Я периодически проверяю базу данных на любое изменение количества хостов. Если есть больше хостов, я запускаю другой поток. Если есть меньше хостов, мне нужно убить конкретный поток, который контролировал этот узел. Как убить конкретный поток.

enter code here protected static void GetThreads()
    {
        Thread[] threads;
        do
        {
            dt = getIP_Poll_status();
            threads = new Thread[dt.Rows.Count];
            Console.WriteLine(dt.Rows.Count + " Threads");
            for (int i = 0; i < threads.Length; ++i)
            {
                string ip = dt.Rows[i][0].ToString();
                int sleep = Convert.ToInt32(dt.Rows[i][1].ToString());
                string status = dt.Rows[i][2].ToString();
                string host = dt.Rows[i][3].ToString();
                Hosts.Add(host);
                string port = dt.Rows[i][4].ToString();
                //Console.WriteLine("starting on " + ip + " delay  " + sleep+".current status "+status);
                threads[i] = new Thread(PollingThreadStart);
                threads[i].Start(new MyThreadParameters(ip, sleep, status, host, port));
                threads[i].Name = host;

            }
            Thread.Sleep(50000);
        }

        while (true);
    }
Теги:
multithreading

6 ответов

7

Убийство потоков принудительно - плохая идея. Он может оставить систему в неопределенном состоянии.

Вы должны установить флаг (поточно-безопасным способом), чтобы поток завершился соответствующим образом при следующем проверке. Подробнее см. мою статью по теме для получения более подробной информации и примера кода.

Я бы добавил, что использование Sleep - это почти всегда неправильная работа, кстати. Вы должны использовать что-то, что позволяет сделать изящное пробуждение, например Monitor.Wait. Таким образом, когда происходят изменения (например, поток опроса должен умереть), что-то может пробудить поток вверх, если он ждет, и он может сразу заметить изменение.

1

Учитывая, что большая часть ваших потоков будет тратить большую часть своего времени на то, чтобы ничего не делать, ваш дизайн может быть лучше реализован как один поток, который хранит список IP-адресов и время, которое они должны получить после голосования. Держите его отсортированным в порядке очередного времени опроса.

псевдокод:

What time does the next ip address need to be polled?
Sleep till then
Poll the address.
Update the poll time for that address to now + interval.
Resort the list
Repeat.

Всякий раз, когда у вас есть обновление БД, обновляйте список, а затем заказывайте поток для повторной оценки, когда он должен остановиться.

  • 0
    Не могли бы вы подробнее рассказать об этом? Если у меня есть список IP-адресов и с каждым из них связано время опроса, как бы я сделал это в одном потоке?
  • 0
    Итак, ваш поток знает, какие IP-адреса нужно опрашивать, и как часто они должны опрашиваться, поэтому легко определить, какой IP-адрес должен опрашиваться следующим и когда. В этот момент вы проводите опрос, а затем определяете, какой IP вам нужно опросить, и сколько времени вам нужно сделать.
Показать ещё 3 комментария
0

То, что вы пытаетесь сделать, - плохая идея из-за причин, упомянутых выше. Однако вы все равно можете дать потоку имя, которое может быть именем хоста. Вы можете узнать поток, проверив имя и убей его.

0

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

Существуют и другие, возможно, лучшие способы достижения желаемого, но они сложнее...

0

Я бы сказал:

  • Не убивайте потоки. Попросите их умереть, красиво (vie Events или какой-то общий флаг).
  • Будьте осторожны при создании только одного потока на запись в БД. Это может означать, что некоторые неожиданные действия DB, где внезапно у вас много строк, переводится в убийство ОС со слишком большим количеством потоков. Определенно имеют ограничение на количество потоков.
0

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

  • 1
    Учитывая пример кода, я думаю, будет справедливо предположить, что это C #. Я согласен с тем, что ФП должен был сделать это явно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню