43 votes

Ce que "thread safe" signifie vraiment... En termes pratiques

Chers tous, s'il vous plaît, soyez indulgents avec mes questions de débutant

J'ai essayé de convertir des PDF en PNG en utilisant ghostscript, avec ASP.NET et C#. Cependant, j'ai également lu que ghostscript n'est pas thread safe. Mes questions sont donc les suivantes :

1) Que signifie exactement "ghostscript n'est pas thread safe" en termes pratiques ? Quel impact cela a-t-il si je l'utilise dans une application Web ASP.NET(aspx) en direct à laquelle de nombreux utilisateurs simultanés accèdent en même temps ?

2) J'ai également lu sur un autre site que la principale caractéristique de ghostscript ver. 8.63 est le rendu multithread. Cela signifie-t-il que notre problème de thread safe est maintenant résolu ? Est-ce que ghostscript est désormais thread safe ?

3) J'évalue également PDF2Image de PDFTron, qui est censé être thread safe. Mais la licence par processeur n'est pas bon marché. Cela vaut-il la peine de payer le supplément pour "thread safe" ou "not safe" ?

J'apprécie grandement vos conseils, merci.

38voto

Eric Lippert Points 300275

Il est difficile de trouver une définition technique précise qui fasse l'unanimité.

De manière informelle, "thread safe" signifie simplement "se comporte raisonnablement bien lorsqu'il est appelé par plusieurs threads". L'objet ne plantera pas ou ne produira pas de résultats bizarres lorsqu'il sera appelé par plusieurs threads.

La question à laquelle il faut en fait répondre si vous avez l'intention de faire de la programmation multithreading impliquant un objet particulier est "quel est le modèle de threading attendu par l'objet ?".

Il existe un grand nombre de modèles d'enfilage différents. Par exemple, le modèle "free threaded" est "faites ce que vous voulez à partir de n'importe quel thread ; l'objet s'en occupera". C'est le modèle le plus facile à gérer pour vous, et le plus difficile à fournir pour le fournisseur d'objets.

À l'autre extrémité du spectre se trouve le modèle "single threaded" : toutes les instances de tous les objets doivent être accessibles à partir d'un seul thread, point final.

Et puis il y a un tas de trucs au milieu. Le modèle "apartment threaded" est "vous pouvez créer deux instances sur deux threads différents, mais quel que soit le thread que vous utilisez pour créer une instance, c'est le thread que vous devez toujours utiliser pour appeler des méthodes sur cette instance".

Le modèle "rental threaded" est le suivant : "vous pouvez appeler une instance sur deux threads différents, mais vous devez vous assurer que deux threads ne le font jamais en même temps".

Et ainsi de suite. Découvrez le modèle de threading attendu par votre objet avant d'essayer d'écrire du code de threading pour cet objet.

22voto

Will Marcouiller Points 11649

Etant donné qu'une Collection, par exemple, n'est pas un trio :

var myDic = new Dictionary<string, string>();

Dans un environnement multithread, ceci lancera :

string s = null;
if (!myDic.TryGetValue("keyName", out s)) {
    s = new string('#', 10);
    myDic.Add("keyName", s);
}

Pendant qu'un thread travaille en essayant d'ajouter la paire KeyValuePair au dictionnaire myDic, un autre peut TryGetValue(). Comme les collections ne peuvent pas être lues et écrites en même temps, une exception se produira.

Cependant, d'un autre côté, si vous essayez ceci :

// Other threads will wait here until the variable myDic gets unlocked from the preceding thread that has locked it.
lock (myDic) {
    string s = null;
    if (!myDic.TryGetValue("keyName", out s)) {
        s = new string('#', 10);
        myDic.Add("keyName", s);
    }
} // The first thread that locked the myDic variable will now release the lock so that other threads will be able to work with the variable.

Ainsi, le deuxième thread essayant d'obtenir la même valeur de clé "keyName" n'aura pas à l'ajouter au dictionnaire puisque le premier thread l'a déjà ajoutée.

En résumé, threadsafe signifie qu'un objet peut être utilisé par plusieurs threads en même temps, ou qu'il verrouillera les threads de manière appropriée pour vous, sans que vous ayez à vous soucier de la threadsafety.

2. Je ne pense pas que GhostScript est maintenant threadsafe. Il utilise principalement plusieurs threads pour effectuer ses tâches, ce qui lui permet d'offrir de meilleures performances, c'est tout.

3. En fonction de votre budget et de vos besoins, cela peut être intéressant. Mais si vous construisez autour d'un wrapper, vous ne pouvez peut-être verrouiller() que lorsque cela est pratique, ou si vous n'utilisez pas le multithreading vous-même, il n'est certainement pas utile de payer pour la threadsafety. Cela signifie seulement que si VOTRE application utilise le multithreading, vous ne subirez pas les conséquences d'une bibliothèque qui n'est pas threadsafe. À moins que vous n'utilisiez réellement le multithreading, il n'est pas utile de payer pour une bibliothèque threadsafe.

11voto

Ray Johnston Points 418

Je suis un développeur Ghostscript, et je ne répéterai pas la théorie générale sur la sécurité des fils. Nous nous sommes efforcés d'assurer la sécurité thread de GS afin que plusieurs "instances" puissent être créées à l'aide de gsapi_new_instance à partir d'un seul processus, mais nous n'avons pas encore obtenu satisfaction (ce qui inclut nos tests d'assurance qualité). La bibliothèque graphique est, cependant, thread safe et le rendu multi-thread s'appuie sur cela pour nous permettre de lancer plusieurs threads pour rendre les bandes d'une liste d'affichage en parallèle. Le rendu multithread a été soumis à de nombreux tests d'assurance qualité et est utilisé par de nombreux détenteurs de licences commerciales pour améliorer les performances sur les processeurs multi-cœurs.

Vous pouvez parier que nous l'annoncerons lorsque nous prendrons enfin en charge plusieurs instances de GS. La plupart des personnes qui veulent utiliser la GS actuelle à partir d'applications nécessitant plusieurs instances créent des processus distincts pour chaque instance afin que la GS n'ait pas besoin d'être thread safe. La GS peut exécuter un travail tel que déterminé par les options de la liste d'arguments ou les E/S peuvent être acheminées vers/depuis le processus pour fournir des données et collecter les sorties.

10voto

Judah Himango Points 27365

1) Cela signifie que si vous partagez les mêmes objets ou champs Ghostscript entre plusieurs threads, le système se bloquera. Par exemple :

private GhostScript someGSObject = new GhostScript();
...
// Uh oh, 2 threads using shared memory. This can crash!
thread1.Use(someGSObject);
thread2.Use(someGSObject);

2) Je ne pense pas - le rendu multithread suggère que GS utilise en interne plusieurs threads pour effectuer le rendu. Cela ne résout pas le problème de GS qui n'est pas sûr pour une utilisation à partir de plusieurs threads.

3) Y a-t-il une question là-dedans ?

Pour rendre GhostScript sûr pour les threads, assurez-vous que seul un thread à la fois y accède. Vous pouvez le faire via des verrous :

lock(someObject)
{
   thread1.Use(someGSObject);
}
lock(someObject)
{
   thread2.Use(someGSObject);
}

2voto

JasCav Points 18931
  1. Thread safe signifie essentiellement qu'un morceau de code fonctionnera correctement même s'il est accédé par plusieurs threads. De nombreux problèmes peuvent survenir si vous utilisez un code non sécurisé dans une application threadée. Le problème le plus courant est le blocage. Cependant, il existe des problèmes beaucoup plus infâmes (race conditions) qui peuvent être plus problématiques car les problèmes de threads sont notoirement difficiles à déboguer.

  2. Non. Le rendu multithread signifie simplement que GS sera capable d'effectuer un rendu plus rapide parce qu'il utilise des threads pour effectuer le rendu (en théorie, du moins - ce n'est pas toujours vrai en pratique).

  3. Cela dépend vraiment de l'usage que vous voulez faire de votre moteur de rendu. Si vous avez l'intention d'accéder à votre application avec plusieurs threads, alors, oui, vous devrez vous soucier de la sécurité des threads. Sinon, ce n'est pas un gros problème.

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