6
votes

Système d'appel () du programme multithreaded

Nous travaillons sur une application de consommation de mémoire multithreadée écrite en C ++. Nous devons exécuter de nombreux commandes shellscript / Linux (et obtenir le code de retour).

Après avoir lu que article Nous avons clairement compris que ce serait une mauvaise idée d'utiliser le système () dans notre contexte.

Une solution serait à la fourchette après le début du programme et avant de créer des threads Mais la communication avec ce processus peut ne pas être facile (prise, tuyau?).

La deuxième solution que nous avons considérée peut consister en une DAMON dédiée écrite en Python (en utilisant XinetD?) Pour pouvoir traiter nos appels système.

Avez-vous déjà eu ce problème? Comment l'avez-vous résolu?

note: Voici un article plus complet qui explique ce problème: http: //developers.sun. Com / Solaris / Articles / Subprocess / Subprocess.html Ils recommandent d'utiliser POSIX_SPOWN qui utilise VFORK () au lieu de Fork () (utilisé dans le système ()).


3 commentaires

C'est probablement une mauvaise idée de faire référence à la gestion de programmes externes, comme le font des "appels système". En C et C ++, les appels système signifie généralement parler au noyau, c'est-à-dire des appels de niveau du système d'exploitation.


Avez-vous connecté le bon article? Il s'agit d'environ Fourchette () Production de processus enfants à une seule-filetage Même si le parent est multi-fileté et ne dit rien sur système () être une mauvaise idée.


Système () fait une fourchette () et ensuite les pages de l'homme des CF :(


3 Réponses :


0
votes

Vous aurez des questions pour comment vous devez appeler un programme externe (Fork / Exec / Wait, comment sinon), mais ce n'est qu'une partie du problème. Le vrai problème est la planification de cela, je suppose, vous ne voulez pas exécuter trop de programmes externes parallèles.

Sans savoir comment organiser le fil dans votre système, je peux vous avertir pour deux problèmes.

C'est un problème important consiste à conserver la charge faible en limitant la commande externe de la commande / script. Vous pouvez configurer un paramètre, qui indique, combien de commandes externes parallèles doivent fonctionner en même temps. Avant d'appeler une commande externe, vous devriez augmenter une variable qui indique le nombre de processus externes actifs; S'il dépasse le paramètre limite, veillez () certains et réessayez. Après le processus terminé, diminuez cette variable. (L'augmentation et la diminution doivent être mutualisées.)

Un autre problème est que lorsque vous utilisez un programme externe, gérez sa durée de vie. Vous devriez configurer un «délai d'attente» pour chaque processus externe et le tuer s'il est suspendu pendant un moment. Il devrait y avoir un thread "délai d'attente" (ou doit être le fil principal), qui contrôle les autres.


0 commentaires

2
votes

L'article que vous liez pour parler principalement de problèmes si vous fourrez () et que vous ne le suivez pas immédiatement avec un EXEC * (). Comme système () serait généralement mis en œuvre par une fourchette () suivie de EXED () la plupart des problèmes ne s'appliquent pas. Un problème qui s'applique est le point sur la fermeture des descripteurs de fichiers, cependant; Sauf si vous avez des raisons spécifiques à faire autrement, l'ouverture des fichiers avec O_Cloexec par défaut est probablement une bonne règle de base.

Un problème avec Fork () + Exec () de grandes applications de consommation de mémoire est que si votre système d'exploitation est configuré pour ne pas autoriser la mémoire surmonter, la fourchette () peut échouer. Une solution à ceci est de fourche un processus "gestionnaire de processus externe" avant de commencer à attribuer beaucoup de mémoire dans votre processus principal.

La meilleure solution est que si la fonctionnalité que vous avez besoin est disponible en tant que bibliothèque, évitant la nécessité de faire une fourchette en premier lieu. Cela ne réchauffe probablement pas votre cœur à court terme, cependant.


3 commentaires

Fourchette Normalement ne devrait pas échouer simplement parce que surmonter = 0, car les pages sont toujours partagées (au moins, jusqu'à ce qu'ils commencent à diverger)


@ Jørgensen: Le problème est qu'avec OverCommit désactivé, le système d'exploitation doit s'assurer qu'il y a suffisamment d'espace au cas où le processus préféré décide d'écrire à toutes les pages écrities, car le système d'exploitation ne peut pas a priori supposer que le processus ne le fera pas.


@ Jørgensen: Fourchette () Est-ce que échoue si elle considère qu'il n'y a pas assez de mémoire (physique + échange). Été là.



0
votes

Que diriez-vous de cette solution:

Fourchette () Au début de votre programme, et rendez l'enfant dédié à la démarrage et à la gestion de vos programmes extérieurs. Ensuite, demandez au parent de démarrer tous ses threads et faites la logique d'application, envoyant des demandes sur un tuyau lorsqu'elle a besoin d'un processus extérieur.

Cela mettrait des problèmes avec des threads lorsque vous fourrez avant de les commencer.


0 commentaires