首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >任务与连续调度

任务与连续调度
EN

Stack Overflow用户
提问于 2016-04-21 06:44:06
回答 1查看 274关注 0票数 1

假设我有许多CPU密集型任务被转储到默认调度程序中(所有这些任务都一次运行,例如通过Task.Run或带有默认调度程序的Task.Factory.StartNew运行)。每个任务都有一个延续。调度程序将启动一些任务,并将其置于运行状态。当这些任务完成后,调度程序就会将原始任务和延续任务混合在队列中来调度,并且必须在两者之间进行选择。它是如何将连续任务与运行更多的组织任务进行排序的。具体来说,如果一个任务已经完成,并且它有一个连续,那么该延续在调度程序中获得优先级,而不是其他已经排队的任务。

例如,假设sheduler运行多个(T1 & T2)排队任务中的2(T1...Tn&T1...Tn)。当其中一个完成时,调度程序会运行延续C1,还是决定启动T3?它会选择哪一种决定论呢?调度程序是否会选择运行更多的任务,并且在T1结束和它的继续C1开始之间可能会有相当大的延迟?

更新:我运行了一些示例代码并添加了一个答案-,但是我仍然想知道这种观察到的行为是否得到了保证?

EN

回答 1

Stack Overflow用户

发布于 2016-04-21 07:08:28

所以我试了一个样本:

代码语言:javascript
运行
复制
var continuations = new List<Task>();
for (int i = 0; i < 20; i++) {
    int counter = i;
    var continuation = Task.Run(() => {
        Console.WriteLine($"T{counter}: Start.");
        Thread.Sleep(500);
        Console.WriteLine($"T{counter}: Complete.");
    }).ContinueWith(t => {
        Console.WriteLine($"C{counter}: Start.");
        Thread.Sleep(50);
        Console.WriteLine($"C{counter}: Complete.");
    });
    continuations.Add(continuation);
}
Task.WaitAll(continuations.ToArray());

哪个输出-,这意味着调度程序确实优先于启动一个新任务(但这是保证的吗?)

代码语言:javascript
运行
复制
T1: Start.
T2: Start.
T3: Start.
T0: Start.
T1: Complete.
T2: Complete.
T3: Complete.
C1: Start.
C3: Start.
T0: Complete.
C0: Start.
C2: Start.
C1: Complete.
T4: Start.
C3: Complete.
T5: Start.
C0: Complete.
T6: Start.
C2: Complete.
T7: Start.
T4: Complete.
C4: Start.
T5: Complete.
C5: Start.
T6: Complete.
C6: Start.
T7: Complete.
C7: Start.
C4: Complete.
C5: Complete.
T9: Start.
T8: Start.
C7: Complete.
T10: Start.
C6: Complete.
T11: Start.
T8: Complete.
C8: Start.
T9: Complete.
C9: Start.
T11: Complete.
C11: Start.
T10: Complete.
C10: Start.
C9: Complete.
C8: Complete.
T13: Start.
T12: Start.
C11: Complete.
T14: Start.
C10: Complete.

变体。这里,在启动Task和注册延续之间的调用线程上有额外的执行。

代码语言:javascript
运行
复制
var continuations = new List<Task>();
for (int i = 0; i < 20; i++) {
    int counter = i;
    var task = Task.Run(() => {
        Console.WriteLine($"T{counter}: Start.");
        Thread.Sleep(500);
        Console.WriteLine($"T{counter}: Complete.");
    });
    Thread.Sleep(100); // Do some stuff before registering continuation.
    var continuation = task.ContinueWith(t => {
    Console.WriteLine($"C{counter}: Start.");
        Thread.Sleep(150);
        Console.WriteLine($"C{counter}: Complete.");
    });
    continuations.Add(continuation);
}
Task.WaitAll(continuations.ToArray());

结果与上述情况相同,即任务N的延拓被赋予其他排队任务的优先级。

代码语言:javascript
运行
复制
T0: Start.
T1: Start.
T2: Start.
T3: Start.
T0: Complete.
C0: Start.
T1: Complete.
C1: Start.
C0: Complete.
T4: Start.
T2: Complete.
C2: Start.
C1: Complete.
T5: Start.
T3: Complete.
C3: Start.
C2: Complete.
T6: Start.
C3: Complete.
T7: Start.
T4: Complete.
C4: Start.
T5: Complete.
C5: Start.
C4: Complete.
T8: Start.
T6: Complete.
C6: Start.
C5: Complete.
T9: Start.
T7: Complete.
C7: Start.
C6: Complete.
T10: Start.
C7: Complete.
T11: Start.
T8: Complete.
C8: Start.
T9: Complete.
C9: Start.
C8: Complete.
T12: Start.
T10: Complete.
C10: Start.
C9: Complete.
T13: Start.
T11: Complete.
C11: Start.
T14: Start.
C10: Complete.
T15: Start.
C11: Complete.
T16: Start.
T12: Complete.
C12: Start.
T13: Complete.
C13: Start.
T14: Complete.
C14: Start.
C12: Complete.
T17: Start.
T15: Complete.
C15: Start.......

另一个变体。在这里,所有任务都先在scheuler上排队(并且可以被调度为运行),然后再注册连续程序。

代码语言:javascript
运行
复制
const int taskCount = 20;
var tasks = new List<Task>();
for (int i = 0; i < taskCount; i++) {
    int counter = i;
    var task = Task.Run(() => {
        Console.WriteLine($"T{counter}: Start.");
        Thread.Sleep(500);
        Console.WriteLine($"T{counter}: Complete.");
    });
    tasks.Add(task);
}
Thread.Sleep(400);
var continuations = new List<Task>();
for (int i = 0; i < taskCount; i++) {
    int counter = i;
    var continuation = tasks[i].ContinueWith(t => {
        Console.WriteLine($"C{counter}: Start.");
        Thread.Sleep(150);
        Console.WriteLine($"C{counter}: Complete.");
    });
    continuations.Add(continuation);
}
Task.WaitAll(continuations.ToArray());

结果和以前一样--延续优先。

代码语言:javascript
运行
复制
T0: Start.
T2: Start.
T3: Start.
T1: Start.
T1: Complete.
T3: Complete.
T0: Complete.
T2: Complete.
C2: Start.
C0: Start.
C3: Start.
C1: Start.
C2: Complete.
C1: Complete.
C0: Complete.
C3: Complete.
T7: Start.
T4: Start.
T6: Start.
T5: Start.
T6: Complete.
T5: Complete.
T7: Complete.
T4: Complete.
C6: Start.
C5: Start.
C7: Start.
C4: Start.
C7: Complete.
T8: Start.
C5: Complete.
T9: Start.
C6: Complete.
T10: Start.
C4: Complete.
T11: Start.
T8: Complete.
C8: Start.
T10: Complete.
C10: Start.
T9: Complete.
C9: Start.
T11: Complete.
C11: Start.
C8: Complete.
T12: Start.
C9: Complete.
T13: Start.
C10: Complete.
T14: Start.
C11: Complete.
T15: Start.
T14: Complete.
T12: Complete.
C12: Start.
T13: Complete.
C13: Start.
C14: Start.
T15: Complete.
C15: Start.
T16: Start.
C12: Complete.
C13: Complete.
T18: Start.
T17: Start.
C14: Complete.
T19: Start.
C15: Complete.
T16: Complete.
C16: Start.
T18: Complete.
C18: Start.
T17: Complete.
T19: Complete.
C19: Start.
C16: Complete.
C17: Start.
C18: Complete.
C19: Complete.
C17: Complete.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36761619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档