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 : Sélectionner tout - Visualiser dans une fenêtre à part
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
}