3 votes

IPC avec gui (code Java & Natif)

Mon application est composée de 2 parties -

Quelques logiques d'interface graphique en Java. Code natif (principalement Delphi) - l'implémentation de l'interface graphique elle-même.

Java utilise le code natif pour des opérations triviales telles que l'ouverture des fenêtres et la réponse aux événements liés aux entrées de l'utilisateur - la mise en œuvre est effectuée via JNI.

Je suis intéressé à diviser les deux côtés à des processus différents - Quelle serait la meilleure façon de mettre en œuvre l'IPC entre eux sans suspendre le gui ? Je penche pour les sockets TCP ou la mémoire partagée, mais avant de m'y plonger, j'aimerais avoir des commentaires. Les performances et une mise en œuvre simple sont mes principales préoccupations.

Merci d'avance.

3voto

Arnaud Bouchez Points 25855

Si votre problème concerne la consommation de mémoire

Si vous manquez de RAM (comme le suggèrent vos commentaires - mais vous auriez dû mieux l'écrire dans votre question principale : plus vous donnez de détails, meilleures sont les réponses que vous obtenez).

Pourquoi mélangez-vous Java et Delphi ? Java n'est probablement pas un bon candidat pour gérer plus de 1 Go de mémoire, en raison de sa consommation de mémoire plus élevée pour les tâches courantes et de son GC interne. Même si vous exécutez la JVM en 64 bits, vous serez confronté à de nouveaux problèmes de mise à l'échelle : vous devrez écrire un code très spécifique pour gérer une mémoire énorme avec Java.

Pour être juste, les problèmes ne viennent pas de Delphi, mais de la consommation de mémoire de Java. Par conséquent, je pense que vous devriez mieux coder votre couche de données en code natif. Java augmente potentiellement vos problèmes.

Vous pouvez soit :

  • Utilisez le Compilateur Pascal libre pour compiler une bibliothèque 64 bits à partir du code Delphi, puis l'appeler à partir de votre application principale Delphi 32 bits ou de Java en utilisant JNI à l'aide d'un fichier Fichier mappé en mémoire comme pont .
  • Changez la façon dont vous accédez aux données. Vous n'aurez probablement pas besoin d'avoir tous ces giga-octets de données en même temps. Vous pourriez les déposer sur le disque, puis y accéder via des index, qui resteront en RAM. Si vous utilisez Delphi, vous devez soit utiliser votre propre gestion des fichiers (vous pouvez utiliser quelque chose comme notre module Bibliothèque BigTable pour le stockage et l'accès indexé), ou utiliser une base de données (même SQlite3 est capable de gérer des Go de données puisque sa limite est d'environ 140 téraoctets, avec la puissance de SQL pour récupérer uniquement les données).
  • Si vous il faut vraiment rester à Java vous pourriez probablement utiliser une base de données au lieu de simples structures en mémoire. Vous pouvez utiliser SQLite depuis Java, ou une base de données purement Java. Je pense que cela réduira votre consommation de mémoire.

L'approche principale est la suivante : ne garder en mémoire que ce qui est nécessaire, et travailler avec des algorithmes Map/Reduce ou un certain type d'index.

Si votre problème consiste à mélanger les interfaces graphiques entre Java et Delphi

D'après mon expérience, cela pourrait être difficile, car JNI a tendance à utiliser ses propres threads, et la VCL s'attend à ce que tous ses processus soient exécutés dans le thread principal.

Donc vous pouvez soit :

  1. Créer quelques méthodes Delphi, exécutant la méthode VCL Synchronize lorsqu'elle est appelée depuis la JNI pour mettre à jour l'écran.
  2. S'appuyer sur la communication par messages GDI de Windows, c'est-à-dire créer votre propre gestionnaire WM_USER* dans le code Delphi, puis rafraîchir le contenu de l'écran à partir de votre code Java en envoyant simplement des API PostMessage ou SendMessage de bas niveau. De par sa conception, ce système sera sûr pour les threads.
  3. Utilisez une approche apatride : J'aime beaucoup. Comme dans HTTP, votre interface utilisateur agira comme un client, et demandera périodiquement à la couche de données (agissant comme un serveur) des données rafraîchies. Tout ce processus restera dans le thread principal, et pourrait être facilement réalisé via un Timer. Avec un timer, une période de 500 ms pour chaque rafraîchissement est suffisante, et votre application principale restera réactive.

Dans tous les cas...

Pour l'IPC, les fichiers mappés en mémoire sont plus rapides que les sockets, mais les messages GDI sont idéaux lorsqu'il s'agit d'une petite quantité de données. Les sockets sont de bons candidats, et seront rapides même sur une machine locale : le léger surcoût des fichiers Memory Mapped ne sera pas perceptible si la quantité de données transmises n'est que de quelques Ko (jusqu'à 1 Mo par exemple) ; et si vous devez créer une version client légère de votre application, elle fonctionnera toujours.

1voto

martin Points 21

La réponse à votre question dépend de vos besoins (en supposant que vous ayez une bonne raison de diviser l'application de cette manière) :

Si vous devez effectuer des tâches "triviales", c'est-à-dire ne nécessitant pas un transfert de données important, il est probablement préférable d'utiliser des sockets. Vous devez néanmoins créer un protocole, par exemple respecter les ordres d'octets. Veuillez également noter que la transmission de données ralentira les réponses de votre gui.

Si vous devez transférer de grandes quantités de données, l'utilisation de la mémoire partagée mayo être plus performant. Veuillez noter qu'ici, vous devez vous occuper vous-même de la comptabilité, qui est effectuée par l'implémentation de tcp (par exemple, un tampon de transmission/réception). En utilisant ceci, le problème de la nécessité d'un protocole devient encore pire.

0voto

Misha Points 2012

Si vous souhaitez une mise en œuvre simple, ne divisez pas l'application en deux processus. En termes de performances, ce n'est pas un problème, mais vous ajoutez un niveau de complexité supérieur à ce qui est nécessaire pour une seule application. Vous devez avoir une très bonne raison de diviser l'application en plusieurs processus pour surmonter le temps et les efforts qu'il vous en coûtera pour fournir la même fonctionnalité avec cette architecture.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X