如何从一组线程中杀死一个特定的线程

时间:2009-06-19 10:50:30

标签: c# .net multithreading

我正在根据数据库中的记录数创建一个线程数组。然后每个线程轮询一个ipaddress,然后休眠一段时间,然后再次重新加载。我会定期检查数据库中主机数量的任何变化。如果有更多的主机我开始另一个线程。如果主机较少,我需要杀死监视该主机的特定线程。我如何杀死特定的线程。

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);
    }

6 个答案:

答案 0 :(得分:7)

强行杀死线程是一个坏主意。它可以使系统处于不确定状态。

您应该设置一个标志(以线程安全的方式),以便线程在下次检查时适当地自行终止。有关详细信息和示例代码,请参阅my threading article

我想补充一点,顺便说一句,使用Sleep几乎总是错误的做法。您应该使用允许优雅唤醒的内容,例如Monitor.Wait。这种方式当有变化时(例如轮询线程应该死掉),如果它正在等待,某些东西可以将线程唤醒,并且它可以立即注意到该变化。

答案 1 :(得分: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.

每当您有数据库更新时,请更新列表,然后命令线程在需要停止时重新评估。

答案 2 :(得分:0)

您没有指定要定位的语言,但通常无论语言如何都使用相同的方法。简单地使用一个共享变量,用于在线程停止运行时发出信号。线程应该定期检查值,如果设置它将以优雅的方式停止。通常,这是停止线程的唯一安全方法。

答案 3 :(得分:0)

我会说:

  1. 不要杀死线程。要求他们死得很好(参加活动或一些共享旗帜)。
  2. 每个数据库条目只创建一个线程时要小心。这可能意味着一些意外的数据库活动,突然你有很多行转换为用太多线程杀死操作系统。绝对有线程数限制。

答案 4 :(得分:0)

您可以向要结束的thead发送interrupt signal。已发出信号的线程需要捕获将被引发的ThreadInterruptedException并正常退出。

还有其他可能更好的方法可以达到你想要的效果,但它们更复杂......

答案 5 :(得分:0)

由于上述原因,您要做的是一个坏主意。但是,您仍然可以为线程指定一个可以作为主机名的名称。您可以通过检查名称找出该线程并将其删除。