在学校,我们被介绍给C++11线程。老师给了我们一个简单的评估,那就是用20个线程制作一个基本的网络爬虫。对我来说,线程是非常新的,尽管我确实了解基本知识。
我想提一提的是,我并不是想找人来完成我的评估,因为我已经完成了。我只想了解为什么使用6个线程总是比使用20个线程快。
请参阅下面的代码示例。
main.cpp:
do
{
for (size_t i = 0; i < THREAD_COUNT; i++)
{
threads[i] = std::thread(SweepUrlList);
}
for (size_t i = 0; i < THREAD_COUNT; i++)
{
threads[i].join();
}
std::cout << std::endl;
WriteToConsole();
listUrl = listNewUrl;
listNewUrl.clear();
} while (listUrl.size() != 0);基本上,这为每个工作线程分配要完成的作业,即下面可以找到的方法SweepUrlList,然后加入所有线程。
while (1)
{
mutextGetNextUrl.lock();
std::set<std::string>::iterator it = listUrl.begin();
if (it == listUrl.end())
{
mutextGetNextUrl.unlock();
break;
}
std::string url(*it);
listUrl.erase(*it);
mutextGetNextUrl.unlock();
ExtractEmail(url, listEmail);
std::cout << ".";
}因此,每个工作线程循环,直到ListUrl为空。ExtractEmail是一种下载网页(使用curl)并解析它以从mailto链接中提取电子邮件的方法。ExtractEmail中唯一的阻塞调用如下:
if(email.length() != 0)
{
mutextInsertNewEmail.lock();
ListEmail.insert(email);
mutextInsertNewEmail.unlock();
}欢迎所有答案,并在可能的情况下链接到您发现的任何文档来回答这个问题。
发布于 2015-05-01 15:36:00
这是线程处理的一个相当普遍的问题,其核心是:
您演示的是线程调度。操作系统将与不同的线程一起工作,并在当前无法工作的地方安排工作。
假设您有4个内核和超线程,那么您有8个处理器可以承载负载,但也可以承载其他应用程序(操作系统、C++调试器和要启动的应用程序)。
从理论上讲,在大约8个密集线程之前,您的性能可能还不错。当您到达您的处理器能够有效使用的线程最多的时候,那么线程就开始相互竞争资源。这可以通过糟糕的性能(尤其是密集的应用程序和紧密的循环)来看出。
最后,这是一个简单的答案,但我怀疑你看到了什么。
发布于 2015-05-01 15:36:15
简单的答案是窒息点。你正在做的事情造成了一个瓶颈。当这种情况发生时,就会放慢速度。它可能是您正在进行的活动连接的数量,或者仅仅是线程的数量和内存大小的额外开销(请参见下面关于核心是这些瓶颈之一的答案)。
您将需要设置一系列监视器,以调查您的阻塞点在哪里,以及需要更改什么才能达到规模。每个行业的许多系统每天都面临这个问题。在一端打开节流阀并不等于另一端输出的增加。在这种情况下,它可以减少另一端的输出。
举个例子,个人离开大厅。我们的目标是尽快把100人从大楼里救出来。如果单个文件产生的速率为每1秒1人,那么100秒就可以清除建筑物。我们很多人都能把一半的时间发送给他们,同时派出2人,所以50秒就可以清理大楼了。如果我们把它们并排送出去呢。这扇门只有2米宽,所以8道门的宽度相当于4米,只有50%的第一排门能通过。其他4将导致下一行的阻塞,以此类推。视速度而定,这可能会造成暂时的堵塞,使时间增加10倍。
发布于 2015-05-01 15:36:35
线程是一个操作系统结构。基本上,每个线程的状态(基本上是所有CPU的寄存器和作为进程构造一部分的虚拟内存映射)由操作系统保存。一旦操作系统给出了特定的线程“执行时间”,它就会恢复这个状态并让它运行。一旦这一次结束,它就必须保存这个状态。保存一个特定线程的状态并恢复另一个线程的过程称为上下文切换,它需要大量的时间(通常在几百到1000个CPU周期之间)。
对上下文切换也有额外的惩罚。一些处理器的高速缓存(如称为TLB的虚拟内存转换缓存)必须被刷新,流水线指令将被丢弃等等。通常,您希望尽可能减少上下文切换。
如果您的CPU有4个核心,则4个线程可以同时运行。如果您尝试在一个4核心系统上运行20个线程,那么操作系统必须管理这些线程之间的时间,因此看起来它们似乎是并行运行的。例如,线程1-4将运行50毫秒,然后5-9将运行50毫秒,等等。
因此,如果您的所有线程都在运行CPU密集型操作,通常最有效的方法是让您的程序使用与内核相同数量的线程(有时在windows中称为“处理器”)。如果您有更多的线程而不是内核,那么就必须进行上下文切换,并且这是可以最小化的开销。
https://stackoverflow.com/questions/29989768
复制相似问题