2009-03-18 7 views
1

Je crée une DLL qui doit répondre aux demandes d'une application. L'une des exigences de l'application est qu'un appel ne devrait pas tarder à se terminer.Comment éviter le blocage (C++, Win32)

Say, j'ai une fonction foo(), qui est appelée par l'application hôte:

int foo(arg){ 
    // some code i need to execute, say, 
    LengthyRoutine(); 
    return 0; 
} 

Disons que, foo doit effectuer une tâche (ou appeler une fonction) qui est certain de prendre Longtemps. L'application me permet de définir une variable d'attente; si cette variable est différente de zéro lorsque foo retourne, elle appelle foo encore et encore (réinitialisation de la variable wait avant chaque appel) jusqu'à ce que wait soit retourné 0.

Quelle est la meilleure approche?

Est-ce que je vais:

int foo(arg){ 

    if (inRoutine == TRUE) { 
     wait = 1; 
     return 0; 
    } else { 
     if (doRoutine == TRUE) { 
      LengthyRoutine(); 
      return 0; 
     } 
    } 

    return 0; 
} 

Cela ne résout pas vraiment le problème que LengthyRoutine va prendre beaucoup de temps pour terminer. Dois-je générer un thread qui met à jour inRoutine selon qu'il a terminé ou non sa tâche?

Merci ..

Répondre

7

Frai un autre thread est à peu près la meilleure façon de le faire, assurez-vous simplement définir les variables de résultat avant de définir la variable qui indique que vous avez terminé pour éviter les conditions de course. Si cela est souvent appelé, vous pouvez générer un thread de travail à l'avance et le réutiliser pour éviter la surcharge de démarrage du thread. Une autre solution possible consiste à faire une partie du travail à chaque fois que la fonction est appelée. Cependant, elle passe plus de temps dans la DLL et n'est probablement pas optimale, tout en étant plus complexe à implémenter le code de algos.

+0

Merci Eric. Je n'ai jamais essayé de faire des fils auparavant et je sens que c'est assez difficile à obtenir. Je vais donner un coup de feu :) – krebstar

+0

C'est absolument la meilleure option, mais comme Eric l'a dit, faites attention à la synchronisation des threads – RobS

+0

Je ne suis pas encore au courant des problèmes de synchronisation de thread pour le moment. Je n'ai besoin que d'un thread de travail unique qui exécute la routine, met à jour les variables d'état à certains moments de l'exécution. L'application appelante vérifie ensuite périodiquement ces variables pour savoir quoi faire. Est-ce correct? Y a-t-il ... – krebstar

0

Si une situation rare incroyable où LengthyRoutine() n'est pas le code d'un tiers et vous avez toute la source et il est possible de le séparer alors vous pouvez envisager d'utiliser coroutines.

+0

Eh bien, LongyRoutine est en fait un groupe d'appels à un code tiers; il est possible de diviser les tâches. Cependant, la raison du long temps qu'il faut pour terminer est parce qu'il est lié à IO (en attente d'un autre composant pour terminer sa tâche) .. Désolé, je n'ai pas expliqué cela dans ma question .. – krebstar

+0

ok, sonne comme vous avez besoin un fil séparé ou un processus alors :-) – neoneye

1

Si programmation C, utilisez callback - passez le rappel à foo. Vous devez vous mettre d'accord sur la signature de rappel et faire un peu de ménage pour le déclencher lorsque le travail dans LongyRoutine est terminé.

typedef (void) callbackFunction(void); 

int foo(arg, callbackFunction) 
{ 
    // some code i need to execute, say, 
    // register callback and return right away 
    // Trigger the LengthyRoutine to run after this function returns 

    return 0; 
} 

LengthyRoutine() 
{ 
    // do lenghty routine 

    // now inform the caller with their suppiled callback 
    callbackFunction(); 
} 

essentiellement Observer modèle en C. C++ rend le travail beaucoup plus facile/plus propre à mon avis

+0

Cela semble être une option viable. Je ne connais pas encore beaucoup les callbacks, mais il semble plus facile à implémenter que les threads. +1 – krebstar

+0

@krebstar: Veuillez noter qu'un mécanisme de rappel ne supprime pas le besoin d'un thread de travail - il ne fait que remplacer le besoin de plusieurs appels à la fonction jusqu'à ce que le processus soit terminé. Vous * aurez * besoin d'un thread de travail. – mghie

Questions connexes