我很有趣在Java,C#和C ++中创建线程的实际成本是多少?我知道当线程创建时必须完成一堆操作:分配线程堆栈,初始化描述符等。
但我对实际成本很感兴趣。 C#和Java使用不同的VM和不同的JIT,C ++执行本机代码。因此,所有这些语言中的线程创建时间都不同。我还听说Java中的线程创建比C#慢得多。有人可以就这个问题提供有用的答案和解释吗?
答案 0 :(得分:7)
在C#,Java和Visual C ++中创建10,000个线程的基准:
class Program
{
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000; i++)
{
Thread thread = new Thread(DoNothing);
thread.Start();
}
watch.Stop();
Console.WriteLine(watch.Elapsed);
}
static void DoNothing()
{
//Do Nothing
}
}
结果:1.7638042秒
public class ThreadBencher {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
//Do nothing
}
};
long startTime = System.nanoTime();
for (int i = 0; i < 10000; i++) {
Thread thread = new Thread(r);
thread.start();
}
long stopTime = System.nanoTime();
long totalTime = stopTime - startTime;
System.out.print(totalTime);
}
}
结果:1.514557805秒(或1514557805纳秒)
DWORD WINAPI DoNothing( LPVOID lpParam )
{
return 0;
}
void main()
{
HANDLE ourThreadHandle = 0;
SYSTEMTIME st1;
SYSTEMTIME st2;
int i;
GetLocalTime(&st1);
for (i = 0; i < 10000; i++) {
ourThreadHandle = CreateThread( NULL, 0, DoNothing, 0, 0, NULL);
}
GetLocalTime(&st2);
double dblSt1 = st1.wSecond + (st1.wMilliseconds / 1000);
double dblSt2 = st2.wSecond + (st2.wMilliseconds / 1000);
double result = dblSt2 - dblSt1;
cout << st1.wSecond << "." << st1.wMilliseconds << endl;
cout << st2.wSecond << "." << st2.wMilliseconds << endl;
}
结果(从输出手动计算后):0.925秒
(免责声明:我不太了解C ++,所以C ++代码很好地拼凑在一起)
注意:这是在64位Windows 8环境中完成的。
答案 1 :(得分:5)
创建线程时会发生这种情况。
创建新线程时,它会共享其代码部分,数据部分和操作系统资源,例如与其他线程一起打开文件。但是它被分配了自己的堆栈,寄存器集和程序计数器。
线程费用
线程在内存使用和性能方面对您的程序(和系统)造成了实际成本。每个线程都需要在内核内存空间和程序的内存空间中分配内存。
管理线程和协调其调度所需的核心结构使用有线内存存储在内核中。您的线程的堆栈空间和每线程数据存储在程序的内存空间中。
首先创建并初始化大多数这些结构 创建线程 - 一个可能相对昂贵的过程,因为 与内核进行必要的交互。
其中一些成本是可配置的,例如为辅助线程分配的堆栈空间量。创建线程的时间成本是粗略的近似值,应该仅用于相互比较。根据处理器负载,计算机速度以及可用系统和程序存储器的数量,线程创建时间可能会有很大差异。
线程不消耗内存(除了堆栈,它是 恒定大小);进程消耗内存。线程的全部要点 是他们分享过程状态。
公共语言运行时(CLR)线程的堆栈空间设置为 (由CLR提供)默认情况下为1MB(64位代码线程为4MB)。
在C ++中,它为堆栈保留1MB(它映射其地址空间),但它不一定分配在物理内存中,只是它的一小部分。如果堆栈增长超过生成页面错误并分配更多物理内存。
Java线程创建很昂贵,因为涉及到相当多的工作:
必须为线程堆栈分配和初始化大块内存。
需要进行系统调用以使用主机操作系统创建/注册本机线程。
需要创建,初始化描述符并将其添加到JVM内部数据结构中。
从某种意义上来说它也是昂贵的,只要它存在,线程就会占用资源;例如线程堆栈,从堆栈可以访问的任何对象,JVM线程描述符,OS本机线程描述符。
答案 2 :(得分:0)
C ++通常是一种更快的语言,尽管它可能是一种难学的语言;因此,了解更多基本功能需要更长时间,这可能会减慢您在制作应用程序时对其进行编码的过程