pthread_cleanup_pushÓëpthread_cleanup_popµÄÀí½â
Ò»¡¢ÎªÊ²Ã´»áÓÐpthread_cleanup_pushÓëpthread_cleanup_pop£º
Ò»°ãÀ´Ëµ£¬PosixµÄÏß³ÌÖÕÖ¹ÓÐÁ½ÖÖÇé¿ö£ºÕý³£ÖÕÖ¹ºÍ·ÇÕý³£ÖÕÖ¹¡£Ïß³ÌÖ÷¶¯µ÷ÓÃpthread_exit()»òÕß´ÓÏ̺߳¯ÊýÖÐreturn¶¼½«Ê¹Ïß³ÌÕý³£Í˳ö£¬ÕâÊÇ¿ÉÔ¤¼ûµÄÍ˳ö·½Ê½£»·ÇÕý³£ÖÕÖ¹ÊÇÏß³ÌÔÚÆäËûÏ̵߳ĸÉԤϣ¬»òÕßÓÉÓÚ×ÔÉíÔËÐгö´í£¨±ÈÈç·ÃÎÊ·Ç·¨µØÖ·£©¶øÍ˳ö£¬ÕâÖÖÍ˳ö·½Ê½ÊDz»¿ÉÔ¤¼ûµÄ¡£
²»ÂÛÊÇ¿ÉÔ¤¼ûµÄÏß³ÌÖÕÖ¹»¹ÊÇÒì³£ÖÕÖ¹£¬¶¼»á´æÔÚ×ÊÔ´ÊͷŵÄÎÊÌ⣬ÔÚ²»¿¼ÂÇÒòÔËÐгö´í¶øÍ˳öµÄÇ°ÌáÏ£¬ÈçºÎ±£Ö¤Ïß³ÌÖÕֹʱÄÜ˳ÀûµÄÊͷŵô×Ô¼ºËùÕ¼ÓõÄ×ÊÔ´£¬ÌرðÊÇËø×ÊÔ´£¬¾ÍÊÇÒ»¸ö±ØÐ뿼Âǽâ¾öµÄÎÊÌâ¡£
×î¾³£³öÏÖµÄÇéÐÎÊÇ×ÊÔ´¶ÀÕ¼ËøµÄʹÓãºÏß³ÌΪÁË·ÃÎÊÁÙ½ç×ÊÔ´¶øΪÆä¼ÓÉÏËø£¬µ«ÔÚ·ÃÎʹý³ÌÖб»Íâ½çÈ¡Ïû£¬Èç¹ûÏ̴߳¦ÓÚÏìӦȡÏû״̬£¬ÇÒ²ÉÓÃÒì²½·½Ê½ÏìÓ¦£¬»òÕßÔÚ´ò¿ª¶ÀÕ¼ËøÒÔÇ°µÄÔËÐз¾¶ÉÏ´æÔÚÈ¡Ïûµã£¬Ôò¸ÃÁÙ½ç×ÊÔ´½«ÓÀÔ¶´¦ÓÚËø¶¨×´Ì¬µÃ²»µ½ÊÍ·Å¡£Íâ½çÈ¡Ïû²Ù×÷ÊDz»¿ÉÔ¤¼ûµÄ£¬Òò´ËµÄÈ·ÐèÒªÒ»¸ö»úÖÆÀ´¼ò»¯ÓÃÓÚ×ÊÔ´Êͷŵıà³Ì¡£
ÔÚPOSIXÏß³ÌAPIÖÐÌṩÁËÒ»¸öpthread_cleanup_push()/pthread_cleanup_pop()º¯Êý¶ÔÓÃÓÚ×Ô¶¯ÊÍ·Å×ÊÔ´ --´Ópthread_cleanup_push()µÄµ÷Óõ㵽pthread_cleanup_pop()Ö®¼äµÄ³ÌÐò¶ÎÖеÄÖÕÖ¹¶¯×÷£¨°üÀ¨µ÷Óà pthread_exit()ºÍÈ¡ÏûµãÖÕÖ¹£©¶¼½«Ö´ÐÐpthread_cleanup_push()ËùÖ¸¶¨µÄÇåÀíº¯Êý¡£API¶¨ÒåÈçÏ£º
void pthread_cleanup_push(void (*routine) (void *), void *arg)void pthread_cleanup_pop(int execute)
pthread_cleanup_push()/pthread_cleanup_pop()²ÉÓÃÏÈÈëºó³öµÄÕ»½á¹¹¹ÜÀí£¬void routine(void *arg)º¯ÊýÔÚµ÷ÓÃpthread_cleanup_push()ʱѹÈëÇåÀíº¯ÊýÕ»£¬¶à´Î¶Ôpthread_cleanup_push()µÄµ÷Óý«ÔÚÇåÀíº¯ÊýÕ»ÖÐÐγÉÒ»¸öº¯ÊýÁ´£¬ÔÚÖ´Ðиú¯ÊýÁ´Ê±°´ÕÕѹջµÄÏ෴˳Ðòµ¯³ö¡£execute²ÎÊý±íʾִÐе½pthread_cleanup_pop()ʱÊÇ·ñÔÚµ¯³öÇåÀíº¯ÊýµÄͬʱִÐиú¯Êý£¬Îª0±íʾ²»Ö´ÐУ¬·Ç0ΪִÐУ»Õâ¸ö²ÎÊý²¢²»Ó°ÏìÒì³£ÖÕֹʱÇåÀíº¯ÊýµÄÖ´ÐС£
¶þ¡¢pthread_cleanup_pushÓëpthread_cleanup_pop¸ÉʲôÓãº
±ÈÈçthread1:
Ö´ÐÐ
pthread_mutex_lock(&mutex);
//һЩ»á×èÈû³ÌÐòÔËÐеĵ÷Ó㬱ÈÈçÌ×½Ó×ÖµÄaccept£¬µÈ´ý¿Í»§Á¬½Ó
sock = accept(......); //ÕâÀïÊÇËæ±ãÕÒµÄÒ»¸ö¿ÉÒÔ×èÈûµÄ½Ó¿Ú
pthread_mutex_unlock(&mutex);
Õâ¸öÀý×ÓÖУ¬Èç¹ûÏß³Ì1Ö´ÐÐacceptʱ£¬Ï̻߳á×èÈû£¨Ò²¾ÍÊǵÈÔÚÄÇÀÓпͻ§¶ËÁ¬½ÓµÄʱºò²Å·µ»Ø£¬»òÔò³öÏÖÆäËû¹ÊÕÏ£©£¬Ï̵߳ȴýÖÐ......
ÕâʱºòÏß³Ì2·¢ÏÖÏß³Ì1µÈÁ˺ܾ㬲»Àµ·³ÁË£¬ËûÏë¹ØµôÏß³Ì1£¬ÓÚÊǵ÷ÓÃpthread_cancel()»òÕßÀàËƺ¯Êý£¬ÇëÇóÏß³Ì1Á¢¼´Í˳ö¡£
ÕâʱºòÏß³Ì1ÈÔÈ»ÔÚacceptµÈ´ýÖУ¬µ±ËüÊÕµ½Ïß³Ì2µÄcancelÐźź󣬾ͻá´ÓacceptÖÐÍ˳ö£¬È»ºóÖÕÖ¹Ị̈߳¬×¢ÒâÕâ¸öʱºòÏß³Ì1»¹Ã»ÓÐÖ´ÐУº
pthread_mutex_unlock(&mutex);
Ò²¾ÍÊÇ˵Ëø×ÊԴûÓÐÊÍ·Å£¬Õâ»ØÔì³ÉÆäËûÏ̵߳ÄËÀËøÎÊÌâ¡£
ËùÒÔ±ØÐëÔÚÏ߳̽ÓÊÕµ½cancelºóÓÃÒ»ÖÖ·½·¨À´±£Ö¤Òì³£Í˳ö(Ò²¾ÍÊÇÏß³Ìû´ïµ½ÖÕµã)ʱ¿ÉÒÔ×öÇåÀí¹¤×÷(Ö÷ÒªÊǽâËø·½Ãæ)£¬pthread_cleanup_pushÓëpthread_cleanup_pop¾ÍÊÇÕâÑùµÄ¡£
pthread_cleanup_push(some_clean_func,...)
pthread_mutex_lock(&mutex);
//һЩ»á×èÈû³ÌÐòÔËÐеĵ÷Ó㬱ÈÈçÌ×½Ó×ÖµÄaccept£¬µÈ´ý¿Í»§Á¬½Ó
sock = accept(......); //ÕâÀïÊÇËæ±ãÕÒµÄÒ»¸ö¿ÉÒÔ×èÈûµÄ½Ó¿Ú
pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0);
return NULL;
ÉÏÃæµÄ´úÂ룬Èç¹ûaccept±»cancelºóÏß³ÌÍ˳ö£¬»á×Ô¶¯µ÷ÓÃsome_clean_funcº¯Êý£¬ÔÚÕâ¸öº¯ÊýÖÐÄã¿ÉÒÔÊÍ·ÅËø×ÊÔ´¡£Èç¹ûacceptûÓб»cancel£¬ÄÇôÏ̼߳ÌÐøÖ´ÐУ¬µ±pthread_mutex_unlock(&mutex);±íʾÏß³Ì×Ô¼ºÕýÈ·µÄÊÍ·Å×ÊÔ´ÁË£¬¶øÖ´ÐÐpthread_cleanup_pop(0);Ò²¾ÍÊÇÈ¡ÏûµôÇ°ÃæµÄsome_clean_funcº¯Êý¡£½Ó×ÅreturnÏ߳̾ÍÕýÈ·µÄ½áÊøÁË¡£
²»ÏþµÃÄãÃ÷°×û£¬Í¨Ë×µã¾ÍÊÇ£º
pthread_cleanup_push×¢²áÒ»¸ö»Øµ÷º¯Êý£¬Èç¹ûÄãµÄÏß³ÌÔÚ¶ÔÓ¦µÄpthread_cleanup_pop֮ǰÒì³£Í˳ö(returnÊÇÕý³£Í˳ö£¬ÆäËûÊÇÒì³£)£¬ÄÇôϵͳ¾Í»áÖ´ÐÐÕâ¸ö»Øµ÷º¯Êý(»Øµ÷º¯ÊýÒª×öʲôÄã×Ô¼º¾ö¶¨)¡£µ«ÊÇÈç¹ûÔÚpthread_cleanup_pop֮ǰûÓÐÒì³£Í˳ö£¬pthread_cleanup_pop¾Í°Ñ¶ÔÓ¦µÄ»Øµ÷º¯ÊýÈ¡ÏûÁË£¬
¹ØÓÚÈ¡ÏûµãµÄ½âÊÍ£º
±ÈÈçÄãÖ´ÐУº
printf("thread sleep\n");
sleep(10);
printf("thread wake...\n");
ÔÚsleepº¯ÊýÖУ¬Ïß³Ì˯Ãߣ¬½á¹ûÊÕµ½cancelÐźţ¬ÕâʱºòÏ̴߳ÓsleepÖÐÐÑÀ´£¬µ«ÊÇÏ̲߳»»áÁ¢¿ÌÍ˳ö¡£ÕâÊÇӦΪpthreadÓëC¿â·½ÃæµÄÔÒò(¾ßÌåÊÇɶÎÒÒ²²»Çå³þ)£¬pthreadµÄ½¨ÒéÊÇ£¬Èç¹ûÒ»¸öº¯ÊýÊÇ×èÈûµÄ£¬ÄÇôÄã±ØÐëÔÚÕâ¸öº¯ÊýÇ°ºó½¨Á¢È¡Ïûµã,±ÈÈ磺
printf("thread sleep\n");
pthread_testcancel()£»
sleep(10);
pthread_testcancel()£»
printf("thread wake...\n");
ÕâÑù£¬¾ÍÌí¼ÓÁËÁ½¸öÈ¡Ïûµô¡£ÔÚÖ´Ðе½pthread_testcancelµÄλÖÃʱ£¬Ï̲߳ſÉÄÜÏìÓ¦cancelÍ˳ö½ø³Ì¡£
Èý¡¢ÐèҪעÒ⣺
ÔÐͺܼòµ¥£¬¹¦Äܸúatexit£¨£©²î²»¶à£¬Ö»²»¹ýÒ»¸öÊÇÏß³ÌÒ»¸öÊǽø³Ì¡£ÓÃÀ´ÉèÖÃÔÚpush/popÄÚÏß³ÌÍ˳öʱҪ×öµÄÊÂÇé¡£
pthread_cleanup_pushÓëpthread_cleanup_popÊdzɶԵĺêʵÏÖµÄpushÓëpopÒ»¶¨ÊdzɶԳöÏֵģ¬ÆäʵpushÖаüº¬"{"¶øpopÖаüº¬"}"£¬ÉÙÒ»¸ö²»ÐС£
¡°Ïß³ÌÈ¡Ïûº¯Êý¡±¼´Ï̱߳»È¡Ïû»òÕßÏÂÃæÃèÊöµÄÇé¿ö·¢Éúʱ×Ô¶¯µ÷Óõĺ¯Êý¡£ËüÒ»°ãÓÃÓÚÊÍ·ÅһЩ×ÊÔ´£¬±ÈÈçÊÍ·ÅËø£¬ÒÔÃâÆäËüµÄÏß³ÌÓÀÔ¶ Ò²²»ÄÜ»ñµÃËø£¬¶øÔì³ÉËÀËø¡£
pthread_cleanup_push()º¯ÊýÖ´ÐÐѹջÇåÀíº¯ÊýµÄ²Ù×÷£¬¶øpthread_cleanup_pop()º¯ÊýÖ´ÐдÓÕ»ÖÐɾ³ýÇåÀíº¯ÊýµÄ²Ù×÷¡£
ÔÚÏÂÃæÈýÖÖÇé¿öÏ£¬pthread_cleanup_push()ѹջµÄ¡°ÇåÀíº¯Êý¡±»á±»µ÷Óãº
1, Ï̵߳÷ÓÃpthread_exit()º¯Êý£¬¶ø²»ÊÇÖ±½Óreturn.
2, ÏìӦȡÏûÇëÇóʱ£¬Ò²¾ÍÊÇÓÐÆäËüµÄÏ̶߳ԸÃÏ̵߳÷ÓÃpthread_cancel()º¯Êý¡£
3, ±¾Ï̵߳÷ÓÃpthread_cleanup_pop()º¯Êý£¬²¢ÇÒÆä²ÎÊý·Ç0
×¢Ò⣺
1.µ±pthread_cleanup_pop()º¯ÊýµÄ²ÎÊýΪ0ʱ£¬½ö½öÔÚÏ̵߳÷ÓÃpthread_exitº¯Êý»òÕßÆäËüÏ̶߳Ա¾Ï̵߳÷ÓÃ
pthread_cancelº¯Êýʱ£¬²ÅÔÚµ¯³ö¡°ÇåÀíº¯Êý¡±µÄͬʱִÐиá°ÇåÀíº¯Êý¡±¡£
2.×¢Òâpthread_exitÖÕÖ¹Ïß³ÌÓëÏß³ÌÖ±½ÓreturnÖÕÖ¹Ï̵߳ÄÇø±ð,µ÷ÓÃreturnº¯ÊýÊDz»»áÔÚµ¯³ö¡°ÇåÀíº¯Êý¡±µÄͬʱִÐиá°ÇåÀíº¯ÊýµÄ¡£
3 .pthread_cleanup_push()º¯ÊýÓëpthread_cleanup_pop()º¯Êý±ØÐë³É¶ÔµÄ³öÏÖÔÚͬһ¸öº¯ÊýÖС£
4.ÔÚÏß³ÌËÞÖ÷º¯ÊýÖÐÖ÷¶¯µ÷ÓÃreturn£¬Èç¹ûreturnÓï¾ä°üº¬ÔÚpthread_cleanup_push()/pthread_cleanup_pop()¶ÔÖУ¬Ôò²»»áÒýÆðÇåÀíº¯ÊýµÄÖ´ÐУ¬·´¶ø»áµ¼ÖÂsegment fault¡£
push½øÈ¥µÄº¯Êý¿ÉÄÜÔÚÒÔÏÂÈý¸öʱ»úÖ´ÐУº
1£¬ÏÔʾµÄµ÷ÓÃpthread_exit();
»ò
2£¬ÔÚcancelµãÏ̱߳»cancel¡£
»ò
3£¬pthread_cleanup_pop()µÄ²ÎÊý²»Îª0ʱ¡£
ÒÔÉ϶¯×÷¶¼ÏÞ¶¨ÔÚpush/popº¸ÇµÄ´úÂëÄÚ¡£
[cpp] view plain copy
#include
#include
#include
#include
void * thr_fn(void *);
void cleanup(void *);
int main(int argc,char ** argv)
{
pthread_t tid;
int err;
void * tret;
err=pthread_create(&tid,NULL,thr_fn,NULL);
if(err!=0)
printf("create thread error: %s\n",strerror(err));
err=pthread_join(tid,&tret);
if(err!=0)
printf("thread join error: %s\n",strerror(err));
printf("thread exit code %d\n",(int)tret);
return 0;
}
void cleanup(void * arg)
{
printf("clean : %s\n",(char *)arg);
}
void * thr_fn(void * arg)
{
printf("thread push start.\n");
pthread_cleanup_push(cleanup,"thread first handler");
pthread_cleanup_push(cleanup,"thread second handler");
printf("thread push over.\n");
pthread_exit((void *)1);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
pthread_exit((void *)2);
}
¶îÍâµÄ֪ʶ£º
¶ÔÓÚcancelÐźţ¬Ïß³ÌÓÐÁ½ÖÖ·½·¨£º ºöÂÔ£¬ºÍÏìÓ¦¡£Ä¬ÈÏÊÇÏìÓ¦
½ÓÊÕµ½cancelÐźţ¬Ïß³ÌÓÐÁ½ÖÖ´¦ÀíÀàÐÍ£º Á¢¼´ÏìÓ¦ ºÍ ÑÓ³ÙÏìÓ¦(ÔÚ×î½üµÄÈ¡ÏûµãÏìÓ¦)£¬Ä¬ÈÏÊÇÑÓ³ÙÏìÓ¦