#include "pthread.h" #include "implement.h" int pthread_attr_init (pthread_attr_t * attr) / * * -------------------------- ---------------------------- * DOCPUBLIC * Initialise un attributs de thread objet avec défaut * attributs. * * PARAMETRES * attr * pointeur sur une instance de pthread_attr_t * * * DESCRIPTION * initialise un fil attributs d' objet par défaut * attributs. * * NOTES: * 1) Permet de définir les attributs de fil * * RÉSULTATS * 0 attr initialisé, * ENOMEM mémoire insuffisante pour attr. * * ------------------------------------------------ ------ * / { pthread_attr_t attr_result; if (attr == NULL) { / * Ce n'est pas autorisée. * / Retour EINVAL; } Attr_result = (pthread_attr_t) malloc (sizeof (* attr_result)); if (attr_result == NULL) { retour ENOMEM; } #Ifdef _POSIX_THREAD_ATTR_STACKSIZE / * * Valeur par défaut à la taille zéro. À moins changé explicitement * Permettra Win32 pour définir la taille à celle du fil conducteur *. * / Attr_result-> stacksize = 0; #endif #ifdef _POSIX_THREAD_ATTR_STACKADDR / * FIXME: choisir une valeur plus raisonnable quand nous l' appuyons. * / Attr_result-> stackaddr = NULL; #endif //设置线程默认是怎么退出的 attr_result-> detachstate = PTHREAD_CREATE_JOINABLE; #if HAVE_SIGSET_T memset (& (attr_result-> sigmask), 0, sizeof (sigset_t)); #endif / * HAVE_SIGSET_T * / / * * Win32 définit de nouveaux threads pour THREAD_PRIORITY_NORMAL et * pas à celle du fil parent. Nous choisissons de par défaut * cet arrangement. * /
attr_result-> param.sched_priority = THREAD_PRIORITY_NORMAL; attr_result-> inheritsched = PTHREAD_EXPLICIT_SCHED; attr_result-> contentionscope = PTHREAD_SCOPE_SYSTEM; attr_result-> valide = PTW32_ATTR_VALID; * attr = attr_result; return 0; }
#include " pthread.h " #include " implement.h " #ifndef _UWIN #include <process.h> #endif int pthread_create (pthread_t * tid, const pthread_attr_t * attr, vide * (* début) ( vide *), vide * arg) / * * -------------------------------------------- ---------- * DOCPUBLIC * Cette fonction crée un thread en cours d' exécution de la fonction de démarrage, * faisant passer la valeur du paramètre, « arg ». Le « attr » spécifie argument * en option les attributs de création. * L'identité du nouveau thread est retourné * via « tid », qui ne devrait pas être NULL. * * PARAMETRES * tid * pointeur vers une instance de pthread_t * * attr * pointeur facultatif se rapportant à une instance de pthread_attr_t * * commencer * pointeur vers la routine de départ pour le nouveau thread * * arg * paramètre optionnel passé à 'démarrer' * * * LA DESCRIPTION * Cette fonction crée un thread en cours d' exécution de la fonction de démarrage, * faisant passer la valeur du paramètre, « arg ». Le « attr » arguments * spécifie des attributs de création en option. * L'identité du nouveau thread est retourné * via « tid », qui ne devrait pas être le pointeur NULL. * * RÉSULTATS * 0 fil créé avec succès, * EINVAL attr invalides, * EAGAIN insuffisance des ressources. * * ------------------------------------------------ ------ * / { fil pthread_t; ptw32_thread_t *tp; enregistrer un pthread_attr_t; POIGNÉE threadH= 0 ; int result = EAGAIN; int run = PTW32_TRUE; ThreadParms * parms = NULL; à long STACKSIZE; int priorité; pthread_t soi; / * * Avant de faire quoi que ce soit, vérifiez que tid peut être stocké par * sans invoquer une erreur de protection de la mémoire (segfault). * Assurez - vous que l'affectation ci - dessous ne peut pas être optimisé par le compilateur. * Ceci est assuré par l' attribution conditionnelle à nouveau * tid à la fin. * / Tid -> x = 0 ; si (attr! = NULL) { un = * attr; } Autre { a = NULL; } Si ((thread = ptw32_new ()) == p. NULL) { goto FAIL0; } Tp = (ptw32_thread_t * ) thread.p; priorité = tp-> sched_priority; si ((parms = (ThreadParms *) malloc ( sizeof (* parms))) == NULL) { goto FAIL0; } Parms -> tid = fil; parms -> start = -> arg = commencer; parms arg; #if défini (HAVE_SIGSET_T) / * * Threads posséderez leur sigmask initial de leur fils créateur. * / Auto = pthread_self (); tp -> sigmask = ((ptw32_thread_t *) self.p) -> sigmask; #endif / * HAVE_SIGSET_T * / si (a =! NULL) { STACKSIZE = a-> stacksize; tp -> detachstate = a-> detachstate; priorité = a-> param.sched_priority; #if (THREAD_PRIORITY_LOWEST> THREAD_PRIORITY_NORMAL) / * WinCE * / #else / * Tout le reste * / / * * priorité du fil doit être réglé à un niveau de système valide * sans altérer l'ensemble de la valeur par pthread_attr_setschedparam (). * / / * * PTHREAD_EXPLICIT_SCHED est la valeur par défaut parce que threads Win32 * ne pas hériter de la priorité de leur créateur. Ils sont mis en marche avec * THREAD_PRIORITY_NORMAL (valeur win32). Le résultat de ne pas fournir * un « attr » arg à pthread_create () est équivalent à défaut de * PTHREAD_EXPLICIT_SCHED et THREAD_PRIORITY_NORMAL prioritaire. * / Si (PTHREAD_INHERIT_SCHED == a-> inheritsched) { / * * Si le thread qui a appelé pthread_create () est un fil Win32 * alors la priorité héritée pourrait être le résultat d'un temporaire ajustement du système *. Ce n'est pas le cas pour les threads POSIX. * / #If ! défini (HAVE_SIGSET_T) auto = pthread_self (); #endif priorité = ((ptw32_thread_t *) self.p) -> sched_priority; } #Endif } autre { / * * Par défaut STACKSIZE * / STACKSIZE = PTHREAD_STACK_MIN; } Tp -> state = courir?PThreadStateInitial: PThreadStateSuspended; tp -> clés = NULL; / * * Threads doit être démarré en mode suspendu et repris si nécessaire * après le retour de _beginthreadex nous la poignée. Sinon , nous avons mis en place une condition de course * entre la création et les fils créés. * Notez que nous retenons également une copie locale de la poignée pour une utilisation * par nous dans le cas thread.p-> threadH se Nulled plus tard , mais avant que nous ayons * fini avec elle ici. * / #If ! défini (__MINGW32__) || défini (__MSVCRT__) || défini (__DMC__) tp -> threadH = threadH = (Handle) _beginthreadex (( vide*) NULL, / * Pas d' info de sécurité * / (non signé) STACKSIZE, / * taille de la pile par défaut * / ptw32_threadStart, parms, (non signé) CREATE_SUSPENDED, (non signé *) & (tp-> fil)); si (threadH =! 0 ) { si (a =! NULL) { ( vide ) ptw32_setthreadpriority (fil, SCHED_OTHER, priorité); } Si (run) { ResumeThread (threadH); } } #Else / * __MINGW32__ &&! __MSVCRT__ * / / * * Ce verrou forcera pthread_threadStart () attendre jusqu'à ce que nous avons * la poignée de fil et fixer la priorité. * / ( Vide ) pthread_mutex_lock (& tp-> cancelLock); tp -> threadH = threadH = //线程创建最终调用了这个函数 (poignée) _beginthread (ptw32_threadStart, (unsigned) STACKSIZE, / * taille de la pile par défaut * / parms); / * * Faire le code de retour de correspondance de _beginthreadex. * / Si (threadH == (MANCHE) - 1 L ) { Tp -> threadH = threadH = 0 ; } Autre { si (! Run) { / * * beginthread ne permet pas de créer des drapeaux, donc nous le faisons maintenant. * Notez que se BeginThread crée le fil dans SUSPENDU le mode *, puis appelle ResumeThread pour le démarrer. * / SuspendThread (threadH); } Si (a =! NULL) { ( vide ) ptw32_setthreadpriority (fil, SCHED_OTHER, priorité); } } ( Vide ) pthread_mutex_unlock (& tp->cancelLock); #endif / * __MINGW32__ &&! __MSVCRT__ * / résultat = (threadH! = 0 )? 0 : EAGAIN; / * * L' automne par Intentionnellement * / / * * ------------ * Code d' échec * ------------ * / FAIL0: si (résultat =! 0 ) { ptw32_threadDestroy (thread); tp = NULL; si (parms =! NULL) { libre (parms); } } Autre { fil;* tid = } #ifdef _UWIN si (résultat == 0 ) pthread_count ++ ; #endif retour (résultat); }