在C#中使用Threads和ConcurrentBag

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C#中使用Threads和ConcurrentBag相关的知识,希望对你有一定的参考价值。

我正在用C#构建一个简单的端口扫描器。我已经拥有端口扫描功能,用户传递要使用的线程数以及IP地址范围。所以,我现在所拥有的是我已经解析了范围并创建了一个包含该范围内所有IP地址的ConcurrentBag。我也有一系列线程。所以,它部分看起来像这样:

var ipsInRange = IPAddressRange.Parse(range);

Thread[] hostThreads = new Thread[(int)threads];
ConcurrentBag<IPAddress> ips = new ConcurrentBag<IPAddress>();
foreach (var ip in ipsInRange)
{
    ips.Add(ip);
}

IPAddress address;
while (!ips.IsEmpty)
{
    if (ips.TryTake(out address))
    {
        PortScanner ps = new PortScanner(address);
        ps.Scan();
    }
}

// I want to assign each thread one IP address, create a new PortScanner 
// instance as above, and scan the IP. I want to delete the scanned IPs 
// from the bag. When the thread finishes with scanning, I want to assign 
// a new one to it. I want to continue like this until the bag is empty, 
// i.e. all the IPs are processed.
// So, simply I want to scan multiple IPs at the same time, using the above 
// thread array and the ConcurrentBag containing list of IPs.

虽然,我之前没有使用过ThreadsConcurrentBag,但我想要实现的内容在上面的评论中写道。任何想法如何将上述线程合并到应用程序中?

答案

我建议使用Task Parallel Library而不是自己管理线程。它导致简短且可读的代码,您既不需要处理线程,也不需要处理ConcurrentBag。

如果在端口扫描开始之前知道所有IP地址(即,您不需要在端口扫描期间添加/删除IP地址),代码可以像这样简单:

var ipsInRange = IPAddressRange.Parse(range);

var options = new ParallelOptions()
{
    MaxDegreeOfParallelism = 5// Set number of IP addresses to be processed concurrently
};

Parallel.ForEach(
    ipsInRange,
    options,
    (address) => { PortScanner ps = new PortScanner(address); ps.Scan(); });

如果您需要支持在端口扫描正在进行时可以修改IP地址列表(从其他线程)的场景,您需要在ipsInRange中包装BlockingCollection集合,但是从您的问题来看,我认为不需要。

另一答案

我看到解决方案:

  1. 使用IP地址创建blocking collection
  2. 创建多个任务,从集合中获取并扫描它。 qazxsw poi

你有10个线程,扫描地址,他们会等待,而集合可以给他们下一个元素。

以上是关于在C#中使用Threads和ConcurrentBag的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp threads.c

如何在 C 中使用线程显示并行性?

C++ 随机种子、全局对象和 SDL_Threads

Semaphore and threads in C

独立 std::threads 的 C++ std::vector

Handler,Runnable和Threads有什么不同?