Názorný postup: Ladění paralelní aplikace
Tento názorný postup ukazuje, jak použít Paralelní úlohy a Paralelní hromádky ladit paralelní aplikacev systému windows.Tato okna vám pomohou porozumět a ověřit chování za běhu kódu, který používá Knihovna paralelní úloh (Tpl na disku CD-ROM) nebo Souběžnost Runtime.Tento návod obsahuje ukázkový kód, který obsahuje předdefinované zarážky.Po přerušení kód, návod ukazuje, jak použít Paralelní úlohy a Paralelní hromádky windows ji.
Tento návod je určena uživatelům tyto úkoly:
Jak zobrazit zásobníky volání všechny podprocesy v jednom zobrazení.
Jak zobrazit seznam System.Threading.Tasks.Task instance, které jsou vytvořeny v aplikace.
Jak zobrazit skutečné volání hromádky úkolů namísto podprocesů.
Jak přejít z kódu Paralelní úlohy a Paralelní hromádky windows.
Jak odolat měřítku prostřednictvím seskupení, zvětšení a další související funkce systému windows.
Požadavky
Tento postup předpokládá, že Pouze můj kód je povolena.Na Nástroje nabídkaklepněte na Možnosti, rozbalit ladění uzlu, vyberte Obecnéa pak vyberte Pouze můj kód (pouze spravované). Pokud tuto funkce, můžete pomocí tohoto postupu, ale výsledky mohou lišit z vzorů.
C# vzorku
Pokud používáte ukázkové C#, tento návod, také předpokládá, že externí kód je skrytý.Chcete-li přepnout zda externí kód je zobrazen, klepněte pravým tlačítkem myši název hlavička tabulky Zásobník volání oknoa pak vyberte nebo zrušte Zobrazit externí kód. Pokud tuto funkce, můžete pomocí tohoto postupu, ale výsledky mohou lišit z vzorů.
Ukázka C++
Pokud používáte ukázkové C++, odkazy na externí kód v tomto tématu můžete ignorovat.Externí kód se vztahuje pouze na vzorku C#.
Ilustrace
Ilustrace v tomto tématu zaznamenány systémem čtyřjádrový vzorku C#.Ačkoli ostatní konfigurace můžete použít k provedení tohoto postupu, ilustrace, může lišit od zobrazené v počítači.
Vytvoření projektu vzorku
Ukázkový kód v tomto návodu je aplikace , která nemá žádnou.cíl je pouze vědět, jak pomocí nástroje systému windows ladit paralelní aplikace.
vytvořit ukázkový projekt
Visual Studiona soubor nabídkapřejděte na Nový a klepněte na tlačítko projektu.
V Nainstalované šablonypodoknovyberte buď Visual C#, Visual Basicnebo Visual C++. Spravované jazyků zajistit, aby .NET Framework 4 se zobrazí v poli framework.
Vyberte Aplikace konzoly a klepněte na tlačítko OK.Zůstávají v ladění konfigurace, což je výchozí.
Otevřete soubor cpp, .cs nebo VB kód v projekt.Odstranění jeho obsahu vytvořit soubor prázdný kód.
Vložte následující kód zvoleného jazyka do souboru prázdný kód.
Imports System
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Diagnostics
Module S
Sub Main()
pcount = Environment.ProcessorCount
Console.WriteLine("Proc count = " + pcount.ToString())
ThreadPool.SetMinThreads(4, -1)
ThreadPool.SetMaxThreads(4, -1)
t1 = New Task(AddressOf A, 1)
t2 = New Task(AddressOf A, 2)
t3 = New Task(AddressOf A, 3)
t4 = New Task(AddressOf A, 4)
Console.WriteLine("Starting t1 " + t1.Id.ToString())
t1.Start()
Console.WriteLine("Starting t2 " + t2.Id.ToString())
t2.Start()
Console.WriteLine("Starting t3 " + t3.Id.ToString())
t3.Start()
Console.WriteLine("Starting t4 " + t4.Id.ToString())
t4.Start()
Console.ReadLine()
End Sub
Sub A(ByVal o As Object)
B(o)
End Sub
Sub B(ByVal o As Object)
C(o)
End Sub
Sub C(ByVal o As Object)
Dim temp As Integer = o
Interlocked.Increment(aa)
While (aa < 4)
End While
If (temp = 1) Then
' BP1 - all tasks in C
Debugger.Break()
waitFor1 = False
Else
While (waitFor1)
End While
End If
Select Case temp
Case 1
D(o)
Case 2
F(o)
Case 3, 4
I(o)
Case Else
Debug.Assert(False, "fool")
End Select
End Sub
Sub D(ByVal o As Object)
E(o)
End Sub
Sub E(ByVal o As Object)
' break here at the same time as H and K
While (bb < 2)
End While
'BP2 - 1 in E, 2 in H, 3 in J, 4 in K
Debugger.Break()
Interlocked.Increment(bb)
'after
L(o)
End Sub
Sub F(ByVal o As Object)
G(o)
End Sub
Sub G(ByVal o As Object)
H(o)
End Sub
Sub H(ByVal o As Object)
' break here at the same time as E and K
Interlocked.Increment(bb)
Monitor.Enter(mylock)
While (bb < 3)
End While
Monitor.Exit(mylock)
'after
L(o)
End Sub
Sub I(ByVal o As Object)
J(o)
End Sub
Sub J(ByVal o As Object)
Dim temp2 As Integer = o
Select Case temp2
Case 3
t4.Wait()
Case 4
K(o)
Case Else
Debug.Assert(False, "fool2")
End Select
End Sub
Sub K(ByVal o As Object)
' break here at the same time as E and H
Interlocked.Increment(bb)
Monitor.Enter(mylock)
While (bb < 3)
End While
Monitor.Exit(mylock)
'after
L(o)
End Sub
Sub L(ByVal oo As Object)
Dim temp3 As Integer = oo
Select Case temp3
Case 1
M(oo)
Case 2
N(oo)
Case 4
O(oo)
Case Else
Debug.Assert(False, "fool3")
End Select
End Sub
Sub M(ByVal o As Object)
' breaks here at the same time as N and Q
Interlocked.Increment(cc)
While (cc < 3)
End While
'BP3 - 1 in M, 2 in N, 3 still in J, 4 in O, 5 in Q
Debugger.Break()
Interlocked.Increment(cc)
While (True)
Thread.Sleep(500) ' for ever
End While
End Sub
Sub N(ByVal o As Object)
' breaks here at the same time as M and Q
Interlocked.Increment(cc)
While (cc < 4)
End While
R(o)
End Sub
Sub O(ByVal o As Object)
Dim t5 As Task = Task.Factory.StartNew(AddressOf P, TaskCreationOptions.AttachedToParent)
t5.Wait()
R(o)
End Sub
Sub P()
Console.WriteLine("t5 runs " + Task.CurrentId.ToString())
Q()
End Sub
Sub Q()
' breaks here at the same time as N and M
Interlocked.Increment(cc)
While (cc < 4)
End While
' task 5 dies here freeing task 4 (its parent)
Console.WriteLine("t5 dies " + Task.CurrentId.ToString())
waitFor5 = False
End Sub
Sub R(ByVal o As Object)
If (o = 2) Then
' wait for task5 to die
While waitFor5
End While
'//spin up all procs
Dim i As Integer
For i = 0 To pcount - 4 - 1
Dim t As Task = Task.Factory.StartNew(Sub()
While True
End While
End Sub)
Console.WriteLine("Started task " + t.Id.ToString())
Next
Task.Factory.StartNew(AddressOf T, i + 1 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
Task.Factory.StartNew(AddressOf T, i + 2 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
Task.Factory.StartNew(AddressOf T, i + 3 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
Task.Factory.StartNew(AddressOf T, i + 4 + 5, TaskCreationOptions.AttachedToParent) ' //scheduled
Task.Factory.StartNew(AddressOf T, (i + 5 + 5).ToString(), TaskCreationOptions.AttachedToParent) ' //scheduled
'//BP4 - 1 in M, 2 in R, 3 in J, 4 in R, 5 died
Debugger.Break()
Else
Debug.Assert(o = 4)
t3.Wait()
End If
End Sub
Sub T(ByVal o As Object)
Console.WriteLine("Scheduled run " + Task.CurrentId.ToString())
End Sub
Private t1, t2, t3, t4 As Task
Private aa As Integer = 0
Private bb As Integer = 0
Private cc As Integer = 0
Private waitFor1 As Boolean = True
Private waitFor5 As Boolean = True
Private pcount As Integer
Private mylock As New S2()
End Module
Public Class S2
End Class
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
class S
{
static void Main()
{
pcount = Environment.ProcessorCount;
Console.WriteLine("Proc count = " + pcount);
ThreadPool.SetMinThreads(4, -1);
ThreadPool.SetMaxThreads(4, -1);
t1 = new Task(A, 1);
t2 = new Task(A, 2);
t3 = new Task(A, 3);
t4 = new Task(A, 4);
Console.WriteLine("Starting t1 " + t1.Id.ToString());
t1.Start();
Console.WriteLine("Starting t2 " + t2.Id.ToString());
t2.Start();
Console.WriteLine("Starting t3 " + t3.Id.ToString());
t3.Start();
Console.WriteLine("Starting t4 " + t4.Id.ToString());
t4.Start();
Console.ReadLine();
}
static void A(object o)
{
B(o);
}
static void B(object o)
{
C(o);
}
static void C(object o)
{
int temp = (int)o;
Interlocked.Increment(ref aa);
while (aa < 4)
{
;
}
if (temp == 1)
{
// BP1 - all tasks in C
Debugger.Break();
waitFor1 = false;
}
else
{
while (waitFor1)
{
;
}
}
switch (temp)
{
case 1:
D(o);
break;
case 2:
F(o);
break;
case 3:
case 4:
I(o);
break;
default:
Debug.Assert(false, "fool");
break;
}
}
static void D(object o)
{
E(o);
}
static void E(object o)
{
// break here at the same time as H and K
while (bb < 2)
{
;
}
//BP2 - 1 in E, 2 in H, 3 in J, 4 in K
Debugger.Break();
Interlocked.Increment(ref bb);
//after
L(o);
}
static void F(object o)
{
G(o);
}
static void G(object o)
{
H(o);
}
static void H(object o)
{
// break here at the same time as E and K
Interlocked.Increment(ref bb);
Monitor.Enter(mylock);
while (bb < 3)
{
;
}
Monitor.Exit(mylock);
//after
L(o);
}
static void I(object o)
{
J(o);
}
static void J(object o)
{
int temp2 = (int)o;
switch (temp2)
{
case 3:
t4.Wait();
break;
case 4:
K(o);
break;
default:
Debug.Assert(false, "fool2");
break;
}
}
static void K(object o)
{
// break here at the same time as E and H
Interlocked.Increment(ref bb);
Monitor.Enter(mylock);
while (bb < 3)
{
;
}
Monitor.Exit(mylock);
//after
L(o);
}
static void L(object oo)
{
int temp3 = (int)oo;
switch (temp3)
{
case 1:
M(oo);
break;
case 2:
N(oo);
break;
case 4:
O(oo);
break;
default:
Debug.Assert(false, "fool3");
break;
}
}
static void M(object o)
{
// breaks here at the same time as N and Q
Interlocked.Increment(ref cc);
while (cc < 3)
{
;
}
//BP3 - 1 in M, 2 in N, 3 still in J, 4 in O, 5 in Q
Debugger.Break();
Interlocked.Increment(ref cc);
while (true)
Thread.Sleep(500); // for ever
}
static void N(object o)
{
// breaks here at the same time as M and Q
Interlocked.Increment(ref cc);
while (cc < 4)
{
;
}
R(o);
}
static void O(object o)
{
Task t5 = Task.Factory.StartNew(P, TaskCreationOptions.AttachedToParent);
t5.Wait();
R(o);
}
static void P()
{
Console.WriteLine("t5 runs " + Task.CurrentId.ToString());
Q();
}
static void Q()
{
// breaks here at the same time as N and M
Interlocked.Increment(ref cc);
while (cc < 4)
{
;
}
// task 5 dies here freeing task 4 (its parent)
Console.WriteLine("t5 dies " + Task.CurrentId.ToString());
waitFor5 = false;
}
static void R(object o)
{
if ((int)o == 2)
{
//wait for task5 to die
while (waitFor5) { ;}
int i;
//spin up all procs
for (i = 0; i < pcount - 4; i++)
{
Task t = Task.Factory.StartNew(() => { while (true);});
Console.WriteLine("Started task " + t.Id.ToString());
}
Task.Factory.StartNew(T, i + 1 + 5, TaskCreationOptions.AttachedToParent); //scheduled
Task.Factory.StartNew(T, i + 2 + 5, TaskCreationOptions.AttachedToParent); //scheduled
Task.Factory.StartNew(T, i + 3 + 5, TaskCreationOptions.AttachedToParent); //scheduled
Task.Factory.StartNew(T, i + 4 + 5, TaskCreationOptions.AttachedToParent); //scheduled
Task.Factory.StartNew(T, (i + 5 + 5).ToString(), TaskCreationOptions.AttachedToParent); //scheduled
//BP4 - 1 in M, 2 in R, 3 in J, 4 in R, 5 died
Debugger.Break();
}
else
{
Debug.Assert((int)o == 4);
t3.Wait();
}
}
static void T(object o)
{
Console.WriteLine("Scheduled run " + Task.CurrentId.ToString());
}
static Task t1, t2, t3, t4;
static int aa = 0;
static int bb = 0;
static int cc = 0;
static bool waitFor1 = true;
static bool waitFor5 = true;
static int pcount;
static S mylock = new S();
}
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <ppl.h>
#include <agents.h>
#include <stdio.h>
#include <concrtrm.h>
#include <vector>
CRITICAL_SECTION cs;
using namespace ::std;
using namespace ::std::tr1;
using namespace ::Concurrency;
task_group task4;
task_group task3;
task_group task2;
volatile long aa = 0;
volatile long bb = 0;
volatile long cc = 0;
static bool waitFor1 = true;
static bool waitFor5 = true;
#pragma optimize("", off)
void Spin()
{
for(int i=0;i<50*50000;++i);
}
#pragma optimize("",on)
template<class Func>
class RunFunc
{
Func& m_Func;
int m_o;
public:
RunFunc(Func func,int o):m_Func(func),m_o(o){
};
void operator()()const{
m_Func(m_o);
};
};
void T(int o)
{
cout << "Scheduled run \n";
};
void R(int o)
{
if (o == 2)
{
while (waitFor5) { ;}
Spin();
//use up all processors but 4 by scheduling 4 non-terminating tasks.
int numProcsToBurn = GetProcessorCount() - 4;
int i;
vector<call<int>*> tasks;
for (i = 0; i < numProcsToBurn; i++)
{
tasks.push_back(new call<int>([](int i){while(true)Spin();}));
asend(tasks[i],1);
cout << "Started task \n";
}
task_handle<RunFunc<decltype(T)>> t6(RunFunc<decltype(T)>(T,i + 1 + 5));
task_handle<RunFunc<decltype(T)>> t7(RunFunc<decltype(T)>(T,i + 2 + 5));
task_handle<RunFunc<decltype(T)>> t8(RunFunc<decltype(T)>(T,i + 3 + 5));
task_handle<RunFunc<decltype(T)>> t9(RunFunc<decltype(T)>(T,i + 4 + 5));
task_handle<RunFunc<decltype(T)>> t10(RunFunc<decltype(T)>(T,i + 5 + 5));
task2.run(t6);
task2.run(t7);
task2.run(t8);
task2.run(t9);
task2.run(t10);
//BP4 - 1 in M, 2 in R, 3 in J, 4 in R, 5 died
DebugBreak();
}
else
{
if (o!=4)
throw;
task3.wait();
}
};
void Q()
{
// breaks here at the same time as N and M
InterlockedIncrement(& cc);
while (cc < 4)
{
;
}
// task 5 dies here freeing task 4 (its parent)
cout << "t5 dies\n";
waitFor5 = false;
};
void P()
{
cout << "t5 runs\n";
Q();
};
void O(int o)
{
task_group t5;
t5.run(&P);
t5.wait();
R(o);
};
void N(int o)
{
// breaks here at the same time as M and Q
InterlockedIncrement(&cc);
while (cc < 4)
{
;
}
R(o);
};
void M(int o)
{
// breaks here at the same time as N and Q
InterlockedIncrement(&cc);
while (cc < 3)
{
;
}
//BP3 - 1 in M, 2 in N, 3 still in J, 4 in O, 5 in Q
DebugBreak();
InterlockedIncrement(&cc);
while (true)
Sleep(500); // for ever
};
void L(int oo)
{
int temp3 = oo;
switch (temp3)
{
case 1:
M(oo);
break;
case 2:
N(oo);
break;
case 4:
O(oo);
break;
default:
throw; //fool3
break;
}
}
void K(int o)
{
// break here at the same time as E and H
InterlockedIncrement(&bb);
EnterCriticalSection(&cs);
while (bb < 3)
{
;
}
LeaveCriticalSection(&cs);
Spin();
//after
L(o);
}
void J(int o)
{
int temp2 = o;
switch (temp2)
{
case 3:
task4.wait();
break;
case 4:
K(o);
break;
default:
throw; //fool2
break;
}
}
static void I(int o)
{
J(o);
}
static void H(int o)
{
// break here at the same time as E and K
InterlockedIncrement(&bb);
EnterCriticalSection(&cs);
while (bb < 3)
{
;
}
LeaveCriticalSection(&cs);
Spin();
//after
L(o);
}
static void G(int o)
{
H(o);
}
static void F(int o)
{
G(o);
}
static void E(int o)
{
// break here at the same time as H and K
while (bb < 2)
{
;
}
//BP2 - 1 in E, 2 in H, 3 in J, 4 in K
Spin(); // for native case only
DebugBreak();
InterlockedIncrement(&bb);
//after
L(o);
}
static void D(int o)
{
E(o);
}
static void C(int o)
{
int temp = o;
InterlockedIncrement(&aa);
while (aa < 4)
{
;
}
if (temp == 1)
{
// BP1 - all tasks in C
DebugBreak();
waitFor1 = false;
}
else
{
while (waitFor1)
{
;
}
}
switch (temp)
{
case 1:
D(o);
break;
case 2:
F(o);
break;
case 3:
case 4:
I(o);
break;
default:
throw; //fool
break;
}
}
static void B(int o)
{
C(o);
}
void A(int o)
{
B(o);
}
int main()
{
InitializeCriticalSection(&cs);
task_group tasks;
task_handle<RunFunc<decltype(A)>> t1(RunFunc<decltype(A)>(A,1));
tasks.run(t1);
task_handle<RunFunc<decltype(A)>> t2(RunFunc<decltype(A)>(A,2));
task2.run(t2);
task_handle<RunFunc<decltype(A)>> t3(RunFunc<decltype(A)>(A,3));
task3.run(t3);
task_handle<RunFunc<decltype(A)>> t4(RunFunc<decltype(A)>(A,4));
task4.run(t4);
getchar();
return 1;
}
V nabídce Soubor klikněte na příkaz Uložit vše.
Na sestavení nabídka, klepněte na tlačítko Znovu vytvořit řešení.
Jsou čtyři volání na Debugger.Break (DebugBreak ve vzorku C++), proto není nutné vložení zarážky; Přerušit ladění až čtyřikrát způsobí právě spuštěnou aplikace .
Pomocí okna paralelní hromádky: zobrazení podprocesů
V nabídce Ladit klikněte na příkaz Spustit ladění.Počkejte první zarážka být přístupů.
Zobrazit zásobník volání vlákno
Na ladění nabídkapřejděte na Windows a klepněte na tlačítko vlákna. Ukotvit vláknaokno v dolní části Visual Studio.
Na ladění nabídkapřejděte na Windows a klepněte na tlačítko Zásobník volání. Ukotvit Zásobník voláníokno v dolní Visual Studio.
Poklepejte na vlákno v vláknaokno aktuální. Aktuální podprocesy mít žlutou šipku.Pokud změníte aktuální vlákno, jeho zásobník volání je zobrazen v Zásobník voláníokno.
Přezkoumat paralelní hromádky okno
Na ladění nabídkapřejděte na Windows a klepněte na tlačítko Paralelní hromádky. Ujistěte se, že vlákna je vybrán v okně v levém horním rohu.
Pomocí Paralelní hromádky oknomůžete zobrazit více zásobníky volání současně v jednom zobrazení.Následující obrázek ukazuje Paralelní hromádky okno Zásobník voláníokno.
zásobník volání hlavní vlákno se zobrazí v jednom poli a zásobníky volání pro čtyři podprocesy jsou seskupeny do jiného pole.Čtyři podprocesy jsou seskupeny jejich zásobníku rámečky sdílejí stejnou metoda kontextech; To znamená, že jsou ve stejné metody: A, B, a C.Zobrazení ID vlákno a názvy podprocesů, které sdílejí stejné pole ukazatel myši nad hlavička (4 podprocesů).Aktuální vlákno je zobrazena tučně, jak je znázorněno na následujícím obrázku.
Žlutá šipka označuje aktivní zásobník snímek aktuálního vlákno.Chcete-li získat další informace, umístěte ukazatel myši nad ní
Můžete nastavit, kolik podrobností zobrazit zásobník rámců (Názvy, Typy parametrů, Názvy parametrů, Hodnoty parametru, Čísla řádků a Kompenzuje bajt) klepnutím pravým tlačítkem myši Zásobník voláníokno.
Modré zvýraznění kolem pole znamená, že aktuální vlákno část daného pole.Aktuální vlákno je také uveden tučně zásobníku snímek v popisu.Pokud poklepete na hlavní vlákno v podprocesů okno, můžete sledovat, modré zvýraznění v Paralelní hromádkyodpovídajícím způsobem přesuneokno .
Pokračovat v provádění až do druhého zarážka
Spuštění pokračovat, dokud druhý zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat. Následující obrázek znázorňuje vlákno strom na druhý zarážka.
U první zarážkavšechny čtyři podprocesy přešel z S.A na S.B S.C metod.Informace jsou stále viditelné Paralelní hromádkyokno, ale čtyři podprocesy pokročila dále. Jeden z nich nadále S.D a pak jihovýchodníJiné S.F, S.G a S.H.Dvěma dalšími pokračování S.I a S.J a pak z nich přešel na S.K a druhé pokračování na non - externí kóduživatel .
Například, podržte nad pole hlavička 1 vlákno nebo 2 podprocesů, viz vlákno ID podprocesy.Můžete ukazatel zásobníku rámců zobrazit ID vlákno plus dalších podrobností snímek .Modré zvýraznění označuje aktuální vlákno a žlutá šipka označuje aktivní zásobník snímek aktuálního vlákno.
Ikona hadřík podprocesů (překrývající se modré a červené waved řádky) označují aktivní zásobník rámce fixní podprocesů.V Zásobník voláníokno, poklepejte na S.B přepnout rámců. Paralelní hromádkyokno indikuje aktuální zásobníku snímek aktuálního vlákno pomocí ikony zelené Zahnutou šipku.
V podprocesy oknopřepínání podprocesů a že v zobrazení Paralelní hromádkyokno je aktualizován.
Přepnout na jiný vláknonebo do jiného snímek jiný vláknopomocí zástupcenabídka v Paralelní hromádkyokno. Například S.J tlačítkem, přejděte na Přepínače do rámečkua poté klepněte na příkaz.
Klepněte pravým tlačítkem na S.C a přejděte na Přepínače do rámečku.Jeden z příkazů má zaškrtnutí označující zásobníku snímek aktuálního vlákno.Můžete přepnout do snímek stejné vlákno (pouze zelenou šipkou přesune) nebo můžete přepnout do jiného vlákno (modré zvýraznění přesune také).Následující obrázek znázorňuje podnabídky.
metodakontext přidružen pouze jeden snímek, zobrazí pole hlavička 1 vlákno a poklepáním můžete přepnout na něj. Pokud poklepete na metoda kontext , který má více než 1 snímek s ním spojené, pak v nabídka automaticky zobrazí.Jako ukazatele kontexty metoda oznámení černý trojúhelník vpravo.Klepnutím na tento trojúhelník také zobrazí v zástupce nabídka.
Rozsáhlých aplikací, které mají mnoho podprocesů můžete zaměřit na pouze podmnožinu podprocesů.Paralelní hromádkyokno můžete zobrazit zásobníky volání pouze pro příznakem podprocesů. Na panelu nástrojů klepněte Zobrazit pouze příznakem vedle seznam.
Další v vlákna okno označit příznakem podprocesy postupně zobrazit vzhled jejich zásobníky volání v Paralelní hromádkyokno. označit příznakem podprocesům pomocí zástupcenabídka nebo na první buňku vlákno. Klepněte Zobrazit pouze příznakem tlačítko na panelu nástrojů znovu zobrazit všechny podprocesy.
Pokračovat v provádění až třetí zarážka
Spuštění pokračovat, dokud třetí zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.
Více podprocesů jsou ve stejné metoda , ale nebyl na začátku zásobník volání metoda , metoda se zobrazí v různých oknech.Je například u aktuální zarážka S.L, který má tři podprocesů a zobrazí se ve třech polích.Poklepejte na j.
Všimněte si, že je S.L do dvou polí tučně, uvidíte v opačném případě se zobrazí.Chcete-li zobrazit rámce, který volání do S.L a které rámce je volání, klepněte Přepnout zobrazení metodu tlačítko na panelu nástrojů.Následující obrázek znázorňuje metoda zobrazení Paralelní hromádky okno.
Všimněte si, jak diagram sklopí na vybrané metoda a umístí do jeho vlastní pole uprostřed zobrazení.Callees a volající se zobrazí v horní a dolní.Klepněte Přepnout zobrazení metodu tlačítko opustit tento režim.
V zástupcenabídka Paralelní hromádkyokno obsahuje také následující další položky.
Hexadecimální zobrazení přepíná čísel v popiscích mezi desítkové číslo a šestnáctkovém formátu.
Symbol zatížení informace a Nastavení Symbol otevřený příslušných dialogových oknech.
Přejít do zdrojového kódu a Přejít K rozebrání navigaci v editor vybrané metoda.
Externí kód zobrazí všechny snímky, i když nejsou kód uživatel .Zkuste zobrazit diagram rozbalit tak, aby další snímků (které mohou být vyšedlá, protože pro ně nemáte symboly).
Máte velkých diagramů a kroku k další zarážka, chcete zobrazit automatický posun k aktivní zásobník snímek aktuálního vlákno. je vlákno , který nejprve přístupů zarážka .V Paralelní hromádky okno, ujistěte se, že Automaticky přejít na aktuální snímek zásobníku je tlačítko na panelu nástrojů na.
Než budete pokračovat v Paralelní hromádkyokno, posunutí všech způsobem doleva a úplně dolů.
Pokračovat v provádění až čtvrtý zarážka
Spuštění pokračovat, dokud čtvrtý zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.
Oznámení o způsobu zobrazení autoscrolled na místě.Přepínání podprocesů podprocesů okno nebo přepínač zásobníku snímky Zásobník voláníokno a oznámení jak zobrazení vždy autoscrolls na správné snímek. Vypnout Automaticky přejít na aktuální snímek nástroj možnost a zobrazit rozdíl.
Ptačí perspektivy také pomáhá s velkých diagramů v Paralelní hromádkyokno. Zobrazí Ptačí perspektivy klepnutím na tlačítko mezi posuvníky v pravém dolním rohu okno, jak je znázorněno na následujícím obrázku.
obdélník , rychlý posun kolem diagramu můžete přesunout.
Klepněte do prázdné oblast diagramu a přetáhněte ji na požadované místo je jiným způsobem přesunutí diagramu v libovolném směru.
zvětšit z diagramu stiskněte a podržte klávesu CTRL a přesunutím kolečka myš .Případně klepněte na tlačítko Lupa na panelu nástrojů a potom pomocí nástroje Lupa.
Můžete také zobrazit hromádky namísto zdola nahoru směrem shora dolů klepnutím Nástroje nabídkaklepnutím na Možnostia zaškrtněte nebo zrušte zaškrtnutí políčka ve skupinovém rámečku ladění uzel.
Než budete pokračovat, na ladění nabídkaklepněte na Zastavit ladění Konec spuštění.
Pomocí okna paralelní úlohy a paralelní hromádky okno zobrazení úkoly
Doporučujeme nejdříve dokončit předchozí postupy.
Restartování aplikace až do první zarážka přístupů
Na ladění nabídka, klepněte na tlačítko Spustit ladění a počkejte první zarážka být přístupů.
Na ladění nabídkapřejděte na Windows a klepněte na tlačítko vlákna. Ukotvit vláknaokno v dolní části Visual Studio.
Na ladění nabídkapřejděte na Windows a na Zásobník volání. Ukotvit Zásobník voláníokno v dolní Visual Studio.
Poklepejte na vlákno v vláknaokno umožňuje aktuální. Aktuální podprocesy mít žlutou šipku.Pokud změníte aktuální vlákno, ostatní okna jsou aktualizovány.Dále jsme přezkoumá úkoly.
Na ladění nabídkapřejděte na Windows a klepněte na tlačítko Paralelní úlohy. Následující obrázek ukazuje Paralelní úlohyokno.
Pro každý spuštěnou úlohu můžete číst jeho ID vrácené stejným názvem vlastnost, ID a název vlákno spuštěný, jeho umístění (ukazatele tohoto zobrazí popis, který byl celý zásobník volání).Také pod úkolu sloupce, zobrazí metoda předaný do úloha. jinými slovy počáteční bod.
Můžete řadit všechny sloupce.Všimněte si řazení piktogram , který označuje sloupec a směr řazení.Můžete také změnit pořadí sloupců přetažením myší doleva nebo doprava.
Žlutá šipka označuje aktuální úloha.Úkoly můžete přepínat poklepáním na úloha nebo pomocí zástupce nabídka.Při přepnutí úkolů podkladové vlákno se stane aktuální a ostatní okna jsou aktualizovány.
Při ruční přepnutí z jednoho úloha do jiného, přesune žlutou šipku, ale bílá šipka zobrazuje úloha , který způsobil přerušení ladicího programu.
Pokračovat v provádění až do druhého zarážka
Spuštění pokračovat, dokud druhý zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.
Dříve stav sloupec ukázalo jako spuštění všech úkolů, ale nyní dva úkoly čeká.Úkoly mohou být blokovány mnoho různých důvodů.V stav sloupec ukazatel čekání úloha se dozvíte, proč je blokován.Na následujícím obrázku je například úloha 3 čekání na úloha 4.
Úkol 4, čeká na monitoru vlastněných vlákno přiřazen k úloha 2.
úloha lze označit příznakem klepnutím na tlačítko označit příznakem v prvním sloupci Paralelní úlohyokno.
Příznaky můžete použít ke sledování úkolů mezi různé body přerušení ve stejné relaci ladění nebo filtrovat úkoly, jejichž zásobníky volání jsou uvedeny v Paralelní hromádkyokno.
Pokud jste použili Paralelní hromádkyokno starší, zobrazit podprocesy aplikace . Zobrazení Paralelní hromádkyznovu, ale při zobrazeníokno úkoly aplikace . Provedete to vybráním úkoly do pole v levé horní části.Následující obrázek znázorňuje zobrazení úkoly.
Podprocesy, které není executing aktuálně úkoly nejsou zobrazeny v zobrazení úkolů Paralelní hromádkyokno. Také pro podprocesy filtrování provést úlohy některé zásobníku snímky, které nejsou důležité pro úkoly je z horní a dolní zásobník.
Zobrazení Paralelní úlohyokno znovu. Pravým tlačítkem myši na libovolné hlavička sloupce zobrazíte zástupce nabídka pro sloupec.
zástupcenabídka můžete přidat nebo odebrat sloupce. Například sloupec doména aplikace není vybrána; proto nejsou zobrazeny v seznamu.Klepněte na tlačítko nadřazené.Nadřazené bez hodnot pro všechny čtyři úlohy se zobrazí sloupec.
Pokračovat v provádění až třetí zarážka
Spuštění pokračovat, dokud třetí zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat.
Nový úloha, úloha 5, je nyní spuštěna a nyní čeká úloha 4.Uvidíte proč nastavením ukazatele myši čekající úloha v stavokno. V nadřazené sloupec, oznámení, je tento úloha 4 nadřazeného úloha 5.
Chcete-li lépe vizualizovatpodřízenýnadřazené -relace, klepněte pravým tlačítkem myši nadřazené hlavička sloupce a potom klepněte na Zobrazení podřízená nadřazené. Měli byste vidět na následujícím obrázku.
Všimněte si, že úloha 4 a úloha 5 jsou spuštěny ve stejném vlákno.Tyto informace nejsou zobrazeny v vláknaokno; prohlížení zde je Další výhodou Paralelní úlohyokno. Chcete-li potvrdit, zobrazení Paralelní hromádkyokno. Ujistěte se, že jsou zobrazeny úkoly.Vyhledejte poklepáním na jejich úkoly, 4 a 5 Paralelní úlohyokno. Při provedení, modré zvýraznění Paralelní hromádkyokno je aktualizován. Můžete také vyhledat úkoly, 4 a 5 skenováním na popisy Paralelní hromádkyokno.
V Paralelní hromádky S.P tlačítkemoknoa klepněte na Přejít na vlákno. okno přepne do zobrazení podprocesů a odpovídající snímek je v zobrazení.Oba úkoly můžete zobrazit ve stejném vlákno.
Toto je Další výhodou zobrazení úkolů Paralelní hromádky okno, ve srovnání s podprocesůokno.
Pokračovat v provádění až čtvrtý zarážka
Spuštění pokračovat, dokud třetí zarážka přístupů, na ladění nabídka, klepněte na tlačítko Pokračovat. Klepněte ID hlavička sloupce seřadit podle ID.Měli byste vidět na následujícím obrázku.
Protože dokončení úloha 5 již zobrazen.Pokud není případ v počítači a vzájemné zablokování není zobrazen, kroku jednou stisknutím klávesy F11.
3 Úloh a úloha 4 nyní čeká na sebe a jsou zablokovány.Existují také 5 nových úkolů, které jsou podřízené úloha 2 a nyní naplánováno.Naplánované úlohy jsou úkoly, které byly zahájeny v kódu, ale ještě nebyl spuštěn.Proto jejich umístění a Podprocesu přiřazení sloupce jsou prázdné.
Zobrazení Paralelní hromádkyokno znovu. hlavička každého pole obsahuje popis, který zobrazí názvy a ID vlákno .Přepněte do zobrazení úkolů Paralelní hromádkyokno. Jak ukazuje následující obrázek, umístěte ukazatel myši nad hlavička zobrazit ID úloha a název a stav úloha.
Můžete skupina úkolů podle sloupce.V Paralelní úlohy okno, klepněte pravým tlačítkem myši Stav hlavička sloupce a potom klepněte na skupiny podle stavu. Následující obrázek ukazuje Paralelní úlohyokno seskupeny podle stav.
Můžete také skupina podle dalších sloupců.Seskupení úkolů můžete se zaměřit na dílčí úkoly.Počet položek, které jsou seskupeny má každý sbalitelné skupina .Můžete také rychle označit příznakem všechny položky ve skupina klepnutím příznak vpravo od tlačítka Sbalit tlačítko.
Poslední funkce Paralelní úlohyjeokno Prozkoumat zástupcenabídka zobrazenou pravým tlačítkem myši na úloha.
zástupcenabídka zobrazí různé příkazy, v závislosti na stav úloha. Mohou zahrnovat příkazy kopie, Vybrat vše, Hexadecimální zobrazení, přepínač úkol, Ukotvit přiřazený podproces, Ukotvit všechny podprocesy, ale tento, a Uvolnit přiřazená vlákna, a příznak.
Můžete zakázat podkladové vlákno úlohanebo úkolů, nebo můžete zakázat všechny podprocesy kromě přiřazené.Zmrazené vlákno reprezentována Paralelní úlohy okno tak, jak je v podprocesů oknomodrá Pozastavit ikonu.
SHRNUTÍ
Tento návod prokázáno Paralelní úlohy a Paralelní hromádky ladicí program systému windows.Pomocí těchto oken na reálných projektech, používajících kódu s více podprocesy.Můžete zkoumat paralelní kód napsaný v C++, C# nebo Visual Basic.
Viz také
Úkoly
Názorný postup: Ladění paralelní aplikace
Koncepty
Pomocí okna paralelní hromádky