Cygwin Posix

Cygwin Posix - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 20-12-2011 à 20:53:07    

Bonjour,
 
Je suis actuellement entrain de découvrir POSIX et je me demande comment cygwin gère les threads.
J'ai fait un programme qui permet de créer 3 threads et qui les détachent.
 
Ce que je ne comprends pas c'est que je m'attendais à ce que mes 3threads crées continue à tourner une fois détachée ...
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. void *PrintServer_01(void)
  5. {
  6. puts(" ..Thread Server_01 is running." );
  7. return NULL;
  8. }
  9. void *PrintClient_01(void)
  10. {
  11. puts(" ..Thread Client_01 is running." );
  12. return NULL;
  13. }
  14. void *PrintClient_02(void)
  15. {
  16. puts(" ..Thread Client_02 is running." );
  17. return NULL;
  18. }
  19. int main()
  20. {
  21.     pthread_t Server_01;
  22.     pthread_t Client_01;
  23.     pthread_t Client_02;
  24. int Ret_Code;
  25.     puts ("--Main Init.--" );
  26. /*---------------------------*/
  27. /* Creation du thread Server */
  28. /*---------------------------*/
  29.     Ret_Code = pthread_create(&Server_01, NULL, (void*)PrintServer_01, NULL);
  30. /* Verif. de la creation */
  31. if (Ret_Code == -1)
  32. {
  33.  printf(" ..Creation of the thread Server_01 fails.\n" );
  34.  return EXIT_FAILURE;
  35. }
  36. else
  37. {
  38.  printf(" ..Creation of the thread Server_01 succeeds.\n" );
  39. }
  40. /*------------------------------*/
  41. /* Creation du thread Client_01 */
  42. /*------------------------------*/
  43.     Ret_Code = pthread_create(&Client_01, NULL, (void*)PrintClient_01, NULL);
  44. /* Verif. de la creation */
  45. if (Ret_Code == -1)
  46. {
  47.  printf(" ..Creation of the thread Client_01 fails.\n" );
  48.  return EXIT_FAILURE;
  49. }
  50. else
  51. {
  52.  printf(" ..Creation of the thread Client_01 succeeds.\n" );
  53. }
  54. /*------------------------------*/
  55. /* Creation du thread Client_02 */
  56. /*------------------------------*/
  57.     Ret_Code = pthread_create(&Client_02, NULL, (void*)PrintClient_02,  NULL);
  58. /* Verif. de la creation */
  59. if (Ret_Code == -1)
  60. {
  61.  printf(" ..Creation of the thread Client_02 fails.\n" );
  62.  return EXIT_FAILURE;
  63. }
  64. else
  65. {
  66.  printf(" ..Creation of the thread Client_02 succeeds.\n" );
  67. }
  68. /* Detachement des threads */
  69. pthread_detach(Server_01);
  70. pthread_detach(Client_01);
  71. pthread_detach(Client_02);
  72. puts ("--Main ends.--" );
  73.     return EXIT_SUCCESS;
  74. }


 
Voila ce que j'obtiens dans ma console cygwin:
$./Main.exe
--Main Init.--
 ..Thread Server_01 is running.
 ..Creation of the thread Server_01 succeeds.
 ..Thread Client_01 is running.
_01 succeeds.
 ..Thread Client_01 is running.
 ..Thread Client_02 is running.
 ..Creation of the thread Client_02 succeeds.
--Main ends.--


Message édité par sined40 le 20-12-2011 à 20:54:01
Reply

Marsh Posté le 20-12-2011 à 20:53:07   

Reply

Marsh Posté le 21-12-2011 à 13:41:38    

Détacher un thread ne veut pas dire qu'il va s'exécuter indépendamment de son processus ! (il ne peut exister en dehors de son processus).
Cela veut dire que ses ressources (l'espace mémoire qu'il lui a été attribué à sa création - au sein de l'espace adresse de son processus !) peut être réclamer par le système QUAND ce thread aura finit.

 

Sinon, pour que ton expérience réussisse, il y a deux problèmes à résoudre dans ton code :

 

- Tes threads ne font pas beaucoup de travail pour que tu puisse constater qu'ils continuent de s'exécuter !
Rajoute un sleep de quelque secondes par exemple (ou une boucle de sleep/printf), parce que le puts, il va trop vite pour tes yeux !

 

- Quelque soit le mode de lancement des threads, si main() a finit, les threads qu'elle a lancé seront terminés.
Il faut donc bloquer main() tant que ses petits sont toujours entrain de jouer : appeler pthread_exit(NULL) à la fin de main().

 

Tu peux sinon bloquer sur un fiston bien précis en le "rejoignant" avec pthread_join().. (mais dans ce cas, il ne faut pas le détacher ! Un thread détaché n'est pas "joignable" :)).

 

Bienvenu dans le monde merveilleux des Posix Threads !  :D


Message édité par p-seeker23 le 21-12-2011 à 13:42:51
Reply

Marsh Posté le 21-12-2011 à 19:49:30    

Bonjour,
 
Tout d'abord merci pour ta réponse. J'ai suivi tes conseils et effectivement, j'ai bien ce que j'attends.
As-tu de la documentation à me conseiller ?
 
Merci
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #define SLEEP_TIMEOUT 2
  6. void *PrintServer_01(void)
  7. {
  8. int Index = 0;
  9. while(1)
  10. {
  11.  sleep(SLEEP_TIMEOUT);
  12.  printf(" ..Thread Server_01 is running - Nbr: %05d.\n",Index++);
  13. }
  14.  return NULL;
  15. }
  16. void *PrintClient_01(void)
  17. {
  18. int Index = 0;
  19. while(1)
  20. {
  21.  sleep(SLEEP_TIMEOUT);
  22.  printf(" ..Thread Client_01 is running - Nbr: %05d.\n",Index++);
  23. }
  24.  return NULL;
  25. }
  26. void *PrintClient_02(void)
  27. {
  28. int Index = 0;
  29. while(1)
  30. {
  31.  sleep(SLEEP_TIMEOUT);
  32.  printf(" ..Thread Client_02 is running - Nbr: %05d.\n",Index++);
  33. }
  34.  return NULL;
  35. }
  36. int main()
  37. {
  38.     pthread_t Server_01;
  39.     pthread_t Client_01;
  40.     pthread_t Client_02;
  41. int Ret_Code;
  42.     printf("--Main Init.--\n" );
  43. /*---------------------------*/
  44. /* Creation du thread Server */
  45. /*---------------------------*/
  46.     Ret_Code = pthread_create(&Server_01, NULL, (void*)PrintServer_01, NULL);
  47. /* Verif. de la creation */
  48. if (Ret_Code == -1)
  49. {
  50.  printf(" ..Creation of the thread Server_01 fails.\n" );
  51.  return EXIT_FAILURE;
  52. }
  53. else
  54. {
  55.  printf(" ..Creation of the thread Server_01 succeeds.\n" );
  56. }
  57. /*------------------------------*/
  58. /* Creation du thread Client_01 */
  59. /*------------------------------*/
  60.     Ret_Code = pthread_create(&Client_01, NULL, (void*)PrintClient_01, NULL);
  61. /* Verif. de la creation */
  62. if (Ret_Code == -1)
  63. {
  64.  printf(" ..Creation of the thread Client_01 fails.\n" );
  65.  return EXIT_FAILURE;
  66. }
  67. else
  68. {
  69.  printf(" ..Creation of the thread Client_01 succeeds.\n" );
  70. }
  71. /*------------------------------*/
  72. /* Creation du thread Client_02 */
  73. /*------------------------------*/
  74.     Ret_Code = pthread_create(&Client_02, NULL, (void*)PrintClient_02,  NULL);
  75. /* Verif. de la creation */
  76. if (Ret_Code == -1)
  77. {
  78.  printf(" ..Creation of the thread Client_02 fails.\n" );
  79.  return EXIT_FAILURE;
  80. }
  81. else
  82. {
  83.  printf(" ..Creation of the thread Client_02 succeeds.\n" );
  84. }
  85. /* Detachement des threads */
  86. pthread_detach(Server_01);
  87. pthread_detach(Client_01);
  88. pthread_detach(Client_02);
  89. printf("--Main ends.--\n" );
  90. pthread_exit(NULL);
  91.     return EXIT_SUCCESS;
  92. }


Message édité par sined40 le 21-12-2011 à 19:50:15
Reply

Marsh Posté le 26-12-2011 à 12:59:19    

Bien.
Les pthreads sont un sujet hyper classique, il y a l'embarras des choix pour la doc.
Mais comme t'es déjà initié, cette introduction illustrée sera parfaite pour toi.
->si t'es "anglaisglotte", tant mieux, sinon faut pas avoir peur, c'est principalement des mots techniques, très facile à comprendre.
(de toutes façons, les meilleurs docs sont anglais !)
Si qq1 te recommande "Programming with POSIX Threads", c'est qu'il t'aime pas.
 
A vrai-dire, la notion de thread en elle-même n'est pas si difficile à comprendre que ça, et l'introduction de Blaise Barney délivre l'essentiel à savoir. Pour trouver mieux après ça, il ne sert à rien de délaisser Dieu pour ses saints, le plus simple est d'utiliser la spec elle même. Voici un point d'entrée avec pthread_create().
 
Après, le sujet est plus vaste que ça. Le modèle des threads lui-même est discutable. Tous les modèles de programmation à "partage d'état" (shared state), c-a-d qui utilisent en gros un bout de mémoire partagée pour se synchroniser montrent leur limites avec la taille (du projet). Ils ne sont pas "scalable". Tant que le code ne dépasse pas qqes milliers de lignes, c'est plus ou moins gérable, mais au delà, les "live/deadlocks", "race conditions", et autres "starvations" deviennent un vrai casse-tête à tel point qu'il devient impossible de *garantir* que le code est exempt de tels soucis !
(De même pour la gestion de la mémoire tout simplement, il est déraisonnable de confier les new/malloc/free/delete.. aux développeurs quand le code fait 50 milles lignes. Le ramasse-miettes devient une nécessité. Comme pour les deadlock/race conditions et autres, toute une culture s'est développée autour des fuites de mémoires en tous genres, et autres "overrun" et "overflows" qui posent des risques de stabilité et de sécurité).
 
Avec la pression imposée par l'évolution du matériel (processeurs multiples, GPGPU), plusieurs tentatives ont été faite pour apprivoiser la programmation concurrente, et il est clair que ceux qui veulent simplifier la tache aux développeurs ont beaucoup de mal. En même temps, cela a ravivé d'anciennes techniques qui semblent beaucoup plus saines pour gérer des process parallèles. L'idée étant de supprimer la mémoire partagée, et d'utiliser plutôt un système de "messaging". Dans ce modèle, les protagonistes ne font qu'échanger des messages, et chacun vit dans son enclos bien protégé, où son seul contact avec le monde extérieur est sa boîte aux lettres. Tous les problèmes liée à l'état partagé s'évaporent d'un coup, et il devient soudain possible de monter en volume jusqu'à des dizaines de milliers de process parallèles de façon robuste, et sans y perdre son latin ! (Twitter). Il devient même possible de distribuer le traitement sur le réseau facilement, sans problèmes de locks ingérables..
 
Cela est représenté par le modèle d'acteurs, ou on parle des fois de "système d'agents" (chaque process étant un agent indépendant interagissant avec les autres agents).
 
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed