有没有一种方法可以指定每个方法使用的内核/线程数,而不会阻塞它们。 例: 我有方法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建议在sempahores上发布代码后,我发现我没有做应该做的事情, 信号量的第二种实现:
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()
答案 0 :(得分:1)
向所有人致以帮助。我已经通过运行两个任务来完成了解决方案。我需要2种方法来并行运行并控制每个方法的线程数) 线程数由信号量控制。 示例:
AFTER INSERT
答案 1 :(得分:0)
最简单的方法是添加一些调度逻辑,这些逻辑将根据线程逻辑索引决定执行哪种方法:
var threadService = new ThreadService();
Parallel.For(
0, 6,
index =>
{
if (index < 4)
threadService.RunFirstMethod();
else
threadService.RunSecondMethod();
});
但是,这不能保证方法将在同一内核上独家执行。为此,您需要指定线程-CPU亲和力,这对于.NET来说有点棘手,因为它在系统线程(仅是可以应用CPU亲和力的线程)之上使用自己的线程。 good article此处说明了如何通过外部呼叫完成此操作。