La réponse dépendrait de votre code, utilisez-vous la messagerie Windows, utilisez-vous le thread, etc. En supposant que vous n'utilisiez ni l'un ni l'autre, vous pourriez implémenter votre propre fonction de sommeil à laquelle l'appelant transmet une fonction qui est utilisée pour savoir si le sommeil doit être préempté. Si elle est préemptée, la fonction renvoie le temps restant pour que l'action puisse être poursuivie ultérieurement.
Cela permet au code linéaire de gérer votre situation. J'ai mis au point un échantillon. J'expliquerai les détails.
typedef bool (*preempt)(void);
DWORD timedPreemptableAction (DWORD msTime, preempt fn)
{
DWORD startTick = GetTickCount();
DWORD endTick = startTick + msTime;
DWORD currentTick;
do
{
currentTick = GetTickCount();
}
while (fn () == false && currentTick < endTick);
return currentTick > endTick ? 0 : endTick-currentTick;
}
La fonction clé ci-dessus, obtient l'heure de début en millisecondes, et ne sortira pas avant que le délai n'expire - ou que la fonction fournie par l'utilisateur ne renvoie vrai.
Cette fonction fournie par l'utilisateur pourrait interroger les dispositifs d'entrée tels que la pression d'un clavier, etc. Pour l'instant, pour répondre à votre question, j'ai ajouté une fonction utilisateur qui renvoie vrai, après 3 secondes :
DWORD startToTurnTicks = 0;
bool startToTurn (void)
{
bool preempt = false;
// TODO Implement method of preemption. For now
// just use a static timer, yep a little hacky
//
// 0 = uninitialized
// 1 = complete, no more interruptions
// >1 = starting tick count
if (startToTurnTicks == 0)
{
startToTurnTicks = GetTickCount();
}
else
{
if (startToTurnTicks != 1)
{
if ((startToTurnTicks + 3000) < GetTickCount())
{
startToTurnTicks = 1;
preempt = true;
}
}
}
return preempt;
}
Maintenant nous avons une fonction qui attend pendant N temps et peut sortir, et une fonction utilisateur qui retournera vrai après 3 secondes, maintenant l'appel principal :
bool neverPreempt (void)
{
return false;
}
int main (void)
{
int appResult = 0;
DWORD moveForwardTime = 1000*10;
DWORD turnTime = 1000*3;
DWORD startTicks = GetTickCount();
printf ("forward : %d seconds in\n",
(GetTickCount()-startTicks)/1000);
moveForwardTime = timedPreemptableAction (moveForwardTime, &startToTurn);
printf ("turn : %d seconds in\n",
(GetTickCount()-startTicks)/1000);
turnTime = timedPreemptableAction (turnTime, &neverPreempt);
printf ("turn complete : %d seconds in\n",
(GetTickCount()-startTicks)/1000);
if (moveForwardTime > 0)
{
printf ("forward again : %d seconds in\n",
(GetTickCount()-startTicks)/1000);
moveForwardTime = timedPreemptableAction (moveForwardTime, &neverPreempt);
printf ("forward complete : %d seconds in\n",
(GetTickCount()-startTicks)/1000);
}
return appResult;
}
Dans le code principal, vous voyez que timedPreemptableAction est appelé 3 fois. La première fois, nous passons la fonction utilisateur qui devient vraie après 3 secondes. Ce premier appel se termine après 3 secondes, laissant 7 secondes. La sortie de l'application renvoie :
f:\projects\cmake_test\build\Debug>main
forward : 0 seconds in
turn : 3 seconds in
turn complete : 6 seconds in
forward again : 6 seconds in
forward complete : 13 seconds in
A commencé à avancer à 0 seconde, s'est "arrêté". @3 secondes, restauré @6 et terminé @13.
0->3 + 6->13 = 10 secondes.