穿线还是不穿线?就是那个问题...
对问题的多线程部分的一个简单而正确的答案是:是的,只要 1)根据算法是可行的,并且 2)它涉及 I/O 绑定操作,或者您在 CPU 绑定操作中有多个内核
第一点:可行性
- 为了执行第 2 步,您必须完成第 1 步。还没有多线程
- 第 3 步需要完成第 2 步,但涉及独立的逐行活动(每行一个请求)。答对了!!
- 第 4 步需要在第 3 步完成所有请求。多线程到此结束。
第二点:操作类型
Web 请求是 I/O 绑定操作。你得到最大的利益。由于您正在向同一台服务器执行请求,无论是否容错,您都必须限制查询速率。需要适当调整并发请求的数量,但是如果您在代码中使用常量(如const int NUMBER_OF_THREADS = 4;
),那么您有一个很好的起点。
提案
使用信号量来处理并发请求。
像以前一样,通过读取文件并转换为中间文件来启动程序。
完成后,创建一个固定大小的数组(您说最终文件具有相同的行数,因此您可以分配它),然后为每一行启动一个循环:
- 获取一个以
NUMBER_OF_THREADS
常量初始化的信号量,这将允许主线程激活 4 个并发线程
- 通过将行、目标数组和索引传递给线程来启动线程(实际上不需要将所有这些都作为参数传递,即如果列表是类成员)
循环之后,等待AutoResetEvent
我将简要讨论的
在线程中,执行以下操作:
- 执行网络请求
- 处理结果
- 将结果保存到对应的目标数组行
- 使用方法增加跨线程共享的变量(此处未讨论)
Interlocked.Increment()
if
共享变量equals
行数,then
释放AutoResetEvent
我提到的这样你就可以解锁主线程
调音
从 4 个并发线程开始。尝试将它们增加到 8 并查看性能。我建议你不要超过 12 个线程,但这里的其他人可能会说这可能太多了......这只是尝试失败。