为每个方法并行执行自定义数量 cores/thread 的两个方法
Execute two methods on custom number of cores/thread for each method in parallel
有没有一种方法可以指定每个方法使用的 Cores/threads 的数量而不阻塞它们。
例子:
我有方法A和方法B。
方法A会被调用50次,方法B也会被调用。
假设我有一个 16 核的 CPU。
我想委托方法 A 并行使用 2 个线程,方法 B 4 并且不阻塞它们。
我试过信号量,但它们在任务执行后阻塞和释放。
这是一些示例代码:
注意:threadService 方法只是调用 Thread.Sleep 3 秒
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
for (int i = 0; i < 5; i++)
{
Task t = Task.Run(() => threadService.RunFirstMethod());
}
for (int i = 0; i < 5; i++)
{
Task t = Task.Run(() => threadService.RunSecondMethod());
}
Console.ReadLine();
}
也许这不是个好主意...?任何帮助或建议将不胜感激。
谢谢
第一次尝试使用信号量(不成功):
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Semaphore semaphoreFirstMethod = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphoreFirstMethod.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphoreFirstMethod.Release());
}
Semaphore semaphoreSecondMethod = new Semaphore(2,2);
for (int i = 0; i < 5; i++)
{
semaphoreSecondMethod.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphoreSecondMethod.Release());
}
Console.ReadLine();
}
结果如下:
2018-08-25 15:34:17.7259 INFO RunFirstMethod()
2018-08-25 15:34:17.7259 INFO RunFirstMethod()
2018-08-25 15:34:19.7691 INFO RunFirstMethod()
2018-08-25 15:34:19.7691 INFO RunFirstMethod()
2018-08-25 15:34:21.7775 INFO RunFirstMethod()
2018-08-25 15:34:21.7775 INFO RunSecondMethod()
2018-08-25 15:34:21.7775 INFO RunSecondMethod()
2018-08-25 15:34:23.8053 INFO RunSecondMethod()
2018-08-25 15:34:23.8053 INFO RunSecondMethod()
2018-08-25 15:34:25.8211 INFO RunSecondMethod()
在@mjwills 建议 post 带有信号量的代码之后,我发现我没有做一些应该做的事情,
第二次使用信号量实现:
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphore.Release());
}
});
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphore.Release());
}
});
Console.ReadLine();
}
第二个结果(对我来说没问题):
2018-08-25 15:36:01.0845 INFO RunSecondMethod()
2018-08-25 15:36:01.0855 INFO RunFirstMethod()
2018-08-25 15:36:02.0863 INFO RunFirstMethod()
2018-08-25 15:36:03.0783 INFO RunSecondMethod()
2018-08-25 15:36:03.1386 INFO RunSecondMethod()
2018-08-25 15:36:03.1386 INFO RunFirstMethod()
2018-08-25 15:36:04.0938 INFO RunFirstMethod()
2018-08-25 15:36:05.0877 INFO RunSecondMethod()
2018-08-25 15:36:05.1547 INFO RunSecondMethod()
2018-08-25 15:36:05.1677 INFO RunFirstMethod()
最简单的方法是添加一些调度逻辑,根据线程逻辑索引决定执行哪个方法:
var threadService = new ThreadService();
Parallel.For(
0, 6,
index =>
{
if (index < 4)
threadService.RunFirstMethod();
else
threadService.RunSecondMethod();
});
然而,这并不能保证一个方法将在同一个核心上独占执行。要实现这一点,您需要指定 thread-CPU affinity,这对于 .NET 来说有点棘手,因为它在系统线程之上使用自己的线程,而系统线程只是可以应用 CPU affinity 的线程。这是 good article,它解释了如何通过外部调用完成此操作。
感谢大家的帮助。我通过 运行ning 两项任务完成了解决方案。我需要 2 种方法来并行 运行 并控制每个方法的线程数)
线程数由信号量控制。
示例:
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphore.Release());
}
});
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphore.Release());
}
});
Console.ReadLine();
}
有没有一种方法可以指定每个方法使用的 Cores/threads 的数量而不阻塞它们。 例子: 我有方法A和方法B。 方法A会被调用50次,方法B也会被调用。
假设我有一个 16 核的 CPU。 我想委托方法 A 并行使用 2 个线程,方法 B 4 并且不阻塞它们。 我试过信号量,但它们在任务执行后阻塞和释放。
这是一些示例代码: 注意:threadService 方法只是调用 Thread.Sleep 3 秒
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
for (int i = 0; i < 5; i++)
{
Task t = Task.Run(() => threadService.RunFirstMethod());
}
for (int i = 0; i < 5; i++)
{
Task t = Task.Run(() => threadService.RunSecondMethod());
}
Console.ReadLine();
}
也许这不是个好主意...?任何帮助或建议将不胜感激。 谢谢
第一次尝试使用信号量(不成功):
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Semaphore semaphoreFirstMethod = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphoreFirstMethod.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphoreFirstMethod.Release());
}
Semaphore semaphoreSecondMethod = new Semaphore(2,2);
for (int i = 0; i < 5; i++)
{
semaphoreSecondMethod.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphoreSecondMethod.Release());
}
Console.ReadLine();
}
结果如下:
2018-08-25 15:34:17.7259 INFO RunFirstMethod()
2018-08-25 15:34:17.7259 INFO RunFirstMethod()
2018-08-25 15:34:19.7691 INFO RunFirstMethod()
2018-08-25 15:34:19.7691 INFO RunFirstMethod()
2018-08-25 15:34:21.7775 INFO RunFirstMethod()
2018-08-25 15:34:21.7775 INFO RunSecondMethod()
2018-08-25 15:34:21.7775 INFO RunSecondMethod()
2018-08-25 15:34:23.8053 INFO RunSecondMethod()
2018-08-25 15:34:23.8053 INFO RunSecondMethod()
2018-08-25 15:34:25.8211 INFO RunSecondMethod()
在@mjwills 建议 post 带有信号量的代码之后,我发现我没有做一些应该做的事情, 第二次使用信号量实现:
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphore.Release());
}
});
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphore.Release());
}
});
Console.ReadLine();
}
第二个结果(对我来说没问题):
2018-08-25 15:36:01.0845 INFO RunSecondMethod()
2018-08-25 15:36:01.0855 INFO RunFirstMethod()
2018-08-25 15:36:02.0863 INFO RunFirstMethod()
2018-08-25 15:36:03.0783 INFO RunSecondMethod()
2018-08-25 15:36:03.1386 INFO RunSecondMethod()
2018-08-25 15:36:03.1386 INFO RunFirstMethod()
2018-08-25 15:36:04.0938 INFO RunFirstMethod()
2018-08-25 15:36:05.0877 INFO RunSecondMethod()
2018-08-25 15:36:05.1547 INFO RunSecondMethod()
2018-08-25 15:36:05.1677 INFO RunFirstMethod()
最简单的方法是添加一些调度逻辑,根据线程逻辑索引决定执行哪个方法:
var threadService = new ThreadService();
Parallel.For(
0, 6,
index =>
{
if (index < 4)
threadService.RunFirstMethod();
else
threadService.RunSecondMethod();
});
然而,这并不能保证一个方法将在同一个核心上独占执行。要实现这一点,您需要指定 thread-CPU affinity,这对于 .NET 来说有点棘手,因为它在系统线程之上使用自己的线程,而系统线程只是可以应用 CPU affinity 的线程。这是 good article,它解释了如何通过外部调用完成此操作。
感谢大家的帮助。我通过 运行ning 两项任务完成了解决方案。我需要 2 种方法来并行 运行 并控制每个方法的线程数) 线程数由信号量控制。 示例:
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphore.Release());
}
});
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphore.Release());
}
});
Console.ReadLine();
}