{"id":87,"date":"2017-04-24T23:49:42","date_gmt":"2017-04-24T21:49:42","guid":{"rendered":"http:\/\/www.lab3216.com\/?p=87"},"modified":"2018-11-07T11:25:03","modified_gmt":"2018-11-07T10:25:03","slug":"communication-inter-threads-en-utilisant-une-fifo-thread-safe","status":"publish","type":"post","link":"https:\/\/blog.scribter.com\/?p=87","title":{"rendered":"Communication inter-Threads en utilisant une FIFO thread-safe"},"content":{"rendered":"<h4>But de l&rsquo;application<\/h4>\n<p>L&rsquo;application consiste \u00e0 cr\u00e9er trois threads et \u00e0 les faire communiquer en utilisant une <strong>FIFO thread-safe<\/strong>.<\/p>\n<p>Le premier thread<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">LireFichier<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>charge le contenu d&rsquo;un fichier texte et envoie les caract\u00e8res lus dans une FIFO.<\/p>\n<p>Le second thread<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">calculer<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>r\u00e9cup\u00e8re les caract\u00e8res pr\u00e9sents dans la premi\u00e8re FIFO et convertit les caract\u00e8res minuscules en majuscule puis les envoie dans une seconde FIFO.<\/p>\n<p>Le troisi\u00e8me thread<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">afficher<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>est charg\u00e9 de r\u00e9cup\u00e9rer les caract\u00e8res de la seconde FIFO et de les afficher \u00e0 l&rsquo;\u00e9cran.<\/p>\n<h4>Organisation du code<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-88 aligncenter\" src=\"http:\/\/www.lab3216.com\/wp-content\/uploads\/2017\/04\/image1-300x159.png\" alt=\"\" width=\"468\" height=\"248\" srcset=\"https:\/\/blog.scribter.com\/wp-content\/uploads\/2017\/04\/image1-300x159.png 300w, https:\/\/blog.scribter.com\/wp-content\/uploads\/2017\/04\/image1.png 433w\" sizes=\"auto, (max-width: 468px) 100vw, 468px\" \/><br \/>\nLe programme comporte un fichier<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">main.c<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>qui contient les corps de 3 fonctions<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">LireFichier<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> calculer<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> et afficher<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>qui vont constituer nos threads.<\/p>\n<p>Les fichiers<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">tfile.<span class=\"me1\">h<\/span> et tfile.<span class=\"me1\">c<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>contiennent les d\u00e9clarations et les corps des fonctions utilis\u00e9s par notre <strong>FIFO circulaire thread-safe.<\/strong><\/p>\n<p>Le thread<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">LireFichier<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>ouvre un fichier texte, et enfile les caract\u00e8res lus dans la FIFO jusqu&rsquo;\u00e0 la fin du fichier. Lorsque un caract\u00e8re ne peut pas \u00eatre enfil\u00e9, il sera \u00e0 nouveau enfil\u00e9 lors de l&rsquo;occurrence suivante de la boucle. Lorsque la fin du fichier est atteint, le thread enfile un caract\u00e8re \u00ab\u00a0null\u00a0\u00bb pour signaler la fin du fichier.<\/p>\n<p>Le thread<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">calculer<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>d\u00e9file les caract\u00e8res contenus dans la FIFO, convertit les caract\u00e8res minuscules en majuscule et les enfile dans la seconde FIFO. Lorsque le thread rencontre un caract\u00e8re \u00ab\u00a0null\u00a0\u00bb, il l&rsquo;enfile puis se termine.<\/p>\n<p>Le thread<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">afficher<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>d\u00e9file les caract\u00e8res contenus dans le seconde FIFO et les affiche \u00e0 l&rsquo;\u00e9cran. Lorsqu&rsquo;il rencontre le caract\u00e8re \u00ab\u00a0null\u00a0\u00bb, il se termine.<br \/>\nNotre structure s_file est une file circulaire doublement cha\u00een\u00e9e dans un tableau. Elle comporte un tableau de caract\u00e8res, un pointeur de t\u00eate et un pointeur de queue. Un mutex permet de d\u00e9limiter les sections critiques et deux s\u00e9maphores\u00a0sont utilis\u00e9es comme compteur d\u00a0&lsquo;entr\u00e9e et compteur de sortie qui vont permettre de limiter le contenu de la file.<\/p>\n<p>La fonction<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">initQueue<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>initialise le <strong>s\u00e9maphore sem_f<\/strong> avec la valeur de la taille de la file. Le <strong>s\u00e9maphore sem_e<\/strong> est initialis\u00e9 \u00e0 0. Le <strong>mutex<\/strong> et les pointeurs de t\u00eate et de queue sont aussi initialis\u00e9s par cette fonction.<\/p>\n<p>La fonction<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">push<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>enfile un caract\u00e8re. Le <strong>s\u00e9maphore sem_f<\/strong> est d\u00e9cr\u00e9ment\u00e9 \u00e0 chaque appel. Lorsque la file est pleine, la valeur du s\u00e9maphore est nulle et la thread est bloqu\u00e9e. Ceci emp\u00eache la file de se remplir au del\u00e0 de sa taille. L&rsquo;ajout du caract\u00e8re dans la file et la modification des pointeurs de t\u00eate et de queue sont effectu\u00e9s dans une section critique prot\u00e9g\u00e9e par le <strong>mutex<\/strong> afin que plusieurs modifications simultan\u00e9es ne soient pas possibles. Ensuite, le <strong>s\u00e9maphore sem_e<\/strong> est incr\u00e9ment\u00e9. Ce qui va permettre d&rsquo;indiquer que la file contient des caract\u00e8res. Finalement, le <strong>mutex<\/strong> est d\u00e9bloqu\u00e9 et le thread se termine.<\/p>\n<p>La fonction<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">pull<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>d\u00e9file un caract\u00e8re. Le <strong>s\u00e9maphore sem_e<\/strong> est d\u00e9cr\u00e9ment\u00e9 lorsque un caract\u00e8re est d\u00e9fil\u00e9 et bloque le thread lorsque la file est vide. La lecture et la modification des pointeurs de file sont r\u00e9alis\u00e9es dans une section critique prot\u00e9g\u00e9e par le <strong>mutex.<\/strong> La valeur est retourn\u00e9e et le <strong>s\u00e9maphore sem_f<\/strong> est incr\u00e9ment\u00e9. Le <strong>mutex<\/strong> est lib\u00e9r\u00e9 et le thread se termine.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-89 aligncenter\" src=\"http:\/\/www.lab3216.com\/wp-content\/uploads\/2017\/04\/image2-300x94.png\" alt=\"\" width=\"466\" height=\"146\" srcset=\"https:\/\/blog.scribter.com\/wp-content\/uploads\/2017\/04\/image2-300x94.png 300w, https:\/\/blog.scribter.com\/wp-content\/uploads\/2017\/04\/image2.png 429w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/p>\n<p align=\"center\"><span style=\"font-size: large;\"><span style=\"font-size: medium;\"><i><b>Diagramme temporel de sem_e<\/b><\/i><\/span><\/span><\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-90\" src=\"http:\/\/www.lab3216.com\/wp-content\/uploads\/2017\/04\/image3-300x103.png\" alt=\"\" width=\"469\" height=\"161\" srcset=\"https:\/\/blog.scribter.com\/wp-content\/uploads\/2017\/04\/image3-300x103.png 300w, https:\/\/blog.scribter.com\/wp-content\/uploads\/2017\/04\/image3.png 461w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/p>\n<p align=\"center\"><span style=\"font-size: large;\"><span style=\"font-size: medium;\"><i><b>Diagramme temporel de sem_f<\/b><\/i><\/span><\/span><\/p>\n<h4>Rappel sur les types de s\u00e9maphores\u00a0:<\/h4>\n<ul>\n<li><strong>S\u00e9maphore binaire\u00a0:<\/strong> Il est initialis\u00e9 \u00e0 0 et permet de synchroniser deux threads. En effet, une instruction<\/li>\n<\/ul>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">sem_wait<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>va interrompre le thread. L&rsquo;instruction<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">sem_post<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>dans un autre thread va lib\u00e9rer le thread interrompu. Nous utilisons un s\u00e9maphore binaire sem_e.<\/p>\n<ul>\n<li><strong>S\u00e9maphore utilis\u00e9 comme mutex\u00a0:<\/strong> Il est initialis\u00e9 \u00e0 1 il se comporte comme un mutex.<\/li>\n<\/ul>\n<p>Une instruction<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">sem_wait<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>d\u00e9bute une section critique et une instruction<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"c codecolorer\">sem_post<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>la termine. Nous n&rsquo;utilisons pas ce type de s\u00e9maphore dans notre programme mais nous utilisons un <strong>mutex<\/strong>.<\/p>\n<ul>\n<li><strong>S\u00e9maphore utilis\u00e9 comme compteur\u00a0:<\/strong> Il est initialis\u00e9 \u00e0 une valeur N sup\u00e9rieure \u00e0 1. Il prot\u00e8ge l&rsquo;acc\u00e8s \u00e0 une ressource de taille N. Nous utilisons ce type de s\u00e9maphore afin de prot\u00e9ger notre FIFO.<\/li>\n<\/ul>\n<p>Nous utilisons ici un <strong>s\u00e9maphore binaire sem_e<\/strong> initialis\u00e9 \u00e0 0.<\/p>\n<div class=\"codecolorer-container c default\" style=\"overflow:auto;white-space:nowrap;width:650px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/><\/div><\/td><td><div class=\"c codecolorer\">sem_t sem_e<span class=\"sy0\">;<\/span> <span class=\"co1\">\/\/d\u00e9claration<\/span><br \/>\nsem_init<span class=\"br0\">&#40;<\/span><span class=\"sy0\">&amp;<\/span>amp<span class=\"sy0\">;<\/span>t<span class=\"sy0\">-&amp;<\/span>gt<span class=\"sy0\">;<\/span>sem_e<span class=\"sy0\">,<\/span><span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> <span class=\"co1\">\/\/initialisation<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Ce s\u00e9maphore va emp\u00eacher que le thread d\u00e9file un caract\u00e8re lorsque la file est vide. Il est incr\u00e9ment\u00e9 \u00e0 chaque ajout de caract\u00e8res dans la file.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>But de l&rsquo;application L&rsquo;application consiste \u00e0 cr\u00e9er trois threads et \u00e0 les faire communiquer en utilisant une FIFO thread-safe. Le premier thread 1LireFichier&#40;&#41;; charge le contenu d&rsquo;un fichier texte et envoie les caract\u00e8res lus dans une FIFO. Le second thread 1calculer&#40;&#41;; r\u00e9cup\u00e8re les caract\u00e8res pr\u00e9sents dans la premi\u00e8re FIFO et convertit les caract\u00e8res minuscules en &hellip; <a href=\"https:\/\/blog.scribter.com\/?p=87\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Communication inter-Threads en utilisant une FIFO thread-safe<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ub_ctt_via":"","footnotes":""},"categories":[8],"tags":[],"class_list":["post-87","post","type-post","status-publish","format-standard","hentry","category-system"],"featured_image_src":null,"author_info":{"display_name":"metouisa","author_link":"https:\/\/blog.scribter.com\/?author=1"},"_links":{"self":[{"href":"https:\/\/blog.scribter.com\/index.php?rest_route=\/wp\/v2\/posts\/87","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.scribter.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.scribter.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.scribter.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.scribter.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=87"}],"version-history":[{"count":5,"href":"https:\/\/blog.scribter.com\/index.php?rest_route=\/wp\/v2\/posts\/87\/revisions"}],"predecessor-version":[{"id":183,"href":"https:\/\/blog.scribter.com\/index.php?rest_route=\/wp\/v2\/posts\/87\/revisions\/183"}],"wp:attachment":[{"href":"https:\/\/blog.scribter.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=87"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.scribter.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=87"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.scribter.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=87"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}