Je migre une application multi-thread de HP-UX vers Solaris et jusqu'à présent, tout est OK sauf pour une chose! L'application a un thread qui gère les signaux et, quand certains d'entre eux sont reçus, il exécute un nettoyage (enregistrement, tuer les processus enfant et ainsi de suite).Comportement des threads POSIX différent entre HP-UX et Solaris 10
J'ai réduit le code autant qu'il était possible de faire un exemple simple montrant en quelque sorte le problème:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <synch.h>
#include <iostream>
#include <unistd.h>
using namespace std;
pthread_t m_signalHandlerThread;
sigset_t m_signalSet;
void signalHandler()
{
while (true)
{
cout << "SigWait..." << endl;
sigwait(&m_signalSet, &sig);
cout << "Signal!! : " << sig << endl;
break;
}
cout << "OUT" << endl;
}
void* signalHandlerThreadFunction(void* arg)
{
signalHandler();
return (void*)0;
}
int main()
{
sigemptyset(&m_signalSet);
sigaddset(&m_signalSet, SIGQUIT); //kill -QUIT
sigaddset(&m_signalSet, SIGTERM); //kill
sigaddset(&m_signalSet, SIGINT); //ctrl-C
sigaddset(&m_signalSet, SIGHUP); //reload config
if (pthread_create(&m_signalHandlerThread, NULL, signalHandlerThreadFunction, NULL))
{
cout << "cannot create signal handler thread, system shut down.\n" << endl;
}
int iTimeout = 0;
while (1)
{
if (iTimeout >= 10)
break;
sleep(1);
iTimeout++;
cout << "Waiting... " << iTimeout << endl;
}
cout << "END" << endl;
exit (0);
}
En utilisant la compilation des lignes de commande: Solaris:
CC -m64 -g temp.cpp -D_POSIX_PTHREAD_SEMANTICS -lpthread
HP- UX:
/opt/aCC/bin/aCC +p +DA2.0W -AA -g -z -lpthread -mt -I/usr/include temp.cpp
Exécution des deux applications, le comportement (pression g CTRL + C alors que dans les 10 secondes en boucle):
HP-UX:
./a.out
SigWait...
Waiting... 1
Waiting... 2
Signal!! : 2 <---- CTRL + C
OUT
Waiting... 3
Waiting... 4 <---- CTRL + C again to terminate
Solaris:
./a.out
SigWait...
Waiting... 1
Waiting... 2 <---- CTRL + C
^C
Toute aide sera plus que bienvenu puisque je suis déjà déchirer mon les cheveux (pas beaucoup à gauche) :)!
Merci!
Merci! Cela a résolu mon problème, même dans l'ensemble de l'application. Je ne comprends tout simplement pas pourquoi cela fonctionne sur HP-UX ... peut-être que dans cette implémentation de thread tous les threads reçoivent le signal? – JoaoSantos
"peut-être dans cette implémentation de thread tous les threads reçoivent le signal?" l'application a reçu le signal - mais il peut être manipulé dans n'importe quel thread * random * où il pourrait être manipulé. HP-UX a peut-être remarqué qu'un thread dans votre application utilise sigwait() alors que Solaris n'a pas été dérangé. Signaux vs threads est mieux décrit comme une zone grise où vous ne voulez vraiment pas expérimenter. Même POSIX ne peut pas décrire le comportement dans son intégralité puisque les détails les plus fins diffèrent grandement d'un OS à l'autre. – Dummy00001
Je donne -1 pour cette réponse. Cette réponse est fausse en ce sens que vous ne pouvez pas sérialiser le signal du gestionnaire de signal classique vers un autre thread ou structure de données. Vous devrez utiliser un verrouillage à l'intérieur du gestionnaire de signal et ce n'est pas possible. Il y a très peu de choses que vous pouvez faire dans un gestionnaire de signal, l'utilisation de primitives de verrouillage n'en fait pas partie. – wilx