Pthread, signaux et system IPC vV sortie
Voilà je fais ce petit test pour trouver une fçon de sortir d'un msgrecv() avec une attente infinie.
Avec le code suivant je peux choisir une attente ds le process ou dans le thread. A partir d'une console j'envoie le signal SIGUSR1. Résultat :
_ process : Je sors "brutalement" de mon attente avec errno positionné..
_ thread : Bien que SIGUSR1 soit reçu je ne sors pas de l'attente.
Qqun saurait expliquer cela ? Merci.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include <pthread.h>
//#define PROCESS
#define MSG_PRI_NORMAL 2
#define MSG_LENGTH 256
typedef struct
{
long type;
char cMsg[MSG_LENGTH];
} MSG;
MSG stMsg ;
pthread_t thread ;
int msgq_id = -1 ;
int iRetCode = -1 ;
int maxNBytes = 256 ;
void handler_SIGUSR1(int) ;
void * fn_thread(void *) ;
int main (void)
{
/* Declaration */
struct sigaction action ;
/* Installer le gestionnaire */
action.sa_handler = handler_SIGUSR1 ;
sigemptyset( &(action.sa_mask) ) ;
action.sa_flags = SA_RESTART ;
if(sigaction(SIGUSR1, &action, NULL) != 0)
{
fprintf(stderr, "Erreur %d \n", errno) ;
exit(EXIT_FAILURE) ;
}
/* Creer la MSGQ */
msgq_id = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR) ;
if( msgq_id == -1)
{
perror("error msgqcreate") ;
msgq_id = 0 ;
}
#ifndef PROCESS
/* Creer le pthread */
if( pthread_create(&thread, NULL, fn_thread, NULL) != 0)
{
perror("[main] pthread_create\n") ;
exit(EXIT_FAILURE) ;
}
pthread_join(thread, NULL) ;
#else
fn_thread(NULL) ;
#endif
return EXIT_SUCCESS ;
}
void handler_SIGUSR1(int arg)
{
fprintf(stdout, "Recu SIGUSR1\n");
}
void * fn_thread(void *arg)
{
/* Attendre un message*/
iRetCode = msgrcv(msgq_id, (void *)&stMsg, maxNBytes, - MSG_PRI_NORMAL, 0) ;
if(iRetCode == 0)
{
fprintf(stdout, "[main] msgrcv success\n");
}
else
{
switch(errno)
{
case EACCES:
fprintf(stdout, "[main] mrcv error : Le processus appelant n'a pas de permission de lecture dans la file\n");
break ;
case EINVAL:
fprintf(stdout, "[main] mrcv error : msgqid ou msgsz invalides\n") ;
break ;
case EINTR:
fprintf(stdout, "[main] mrcv error : Un signal est arrivé avant d'avoir pu lire quoi que ce soit\n") ;
break ;
default:
fprintf(stdout, "[main] erreur inconnue\n") ;
break ;
}
}
#ifndef PROCESS
pthread_exit(NULL) ;
#endif
} |