å¨Linuxç³»ç»ä¸ä½¿ç¨C/C++è¿è¡å¤çº¿ç¨ç¼ç¨æ¶ï¼æ们éå°æå¤çå°±æ¯å¯¹åä¸åéçå¤çº¿ç¨è¯»åé®é¢ï¼å¤§å¤æ
åµä¸éå°è¿ç±»é®é¢é½æ¯éè¿éæºå¶æ¥å¤çï¼ä½è¿å¯¹ç¨åºçæ§è½å¸¦æ¥äºå¾å¤§çå½±åï¼å½ç¶å¯¹äºé£äºç³»ç»åçæ¯æååæä½çæ°æ®ç±»åæ¥è¯´ï¼æ们å¯ä»¥ä½¿ç¨ååæä½æ¥å¤çï¼è¿è½å¯¹ç¨åºçæ§è½ä¼å¾å°ä¸å®çæé«ãé£ä¹å¯¹äºé£äºç³»ç»ä¸æ¯æååæä½çèªå®ä¹æ°æ®ç±»åï¼å¨ä¸ä½¿ç¨éçæ
åµä¸å¦ä½åå°çº¿ç¨å®å
¨å¢ï¼æ¬æå°ä»çº¿ç¨å±é¨åå¨æ¹é¢ï¼ç®å讲解å¤çè¿ä¸ç±»çº¿ç¨å®å
¨é®é¢çæ¹æ³ã
ä¸ãæ°æ®ç±»å
å¨C/C++ç¨åºä¸å¸¸åå¨å
¨å±åéãå½æ°å
å®ä¹çéæåé以åå±é¨åéï¼å¯¹äºå±é¨åéæ¥è¯´ï¼å
¶ä¸åå¨çº¿ç¨å®å
¨é®é¢ï¼å æ¤ä¸å¨æ¬æ讨论çèå´ä¹å
ãå
¨å±åéåå½æ°å
å®ä¹çéæåéï¼æ¯åä¸è¿ç¨ä¸å个线ç¨é½å¯ä»¥è®¿é®çå
±äº«åéï¼å æ¤å®ä»¬åå¨å¤çº¿ç¨è¯»åé®é¢ãå¨ä¸ä¸ªçº¿ç¨ä¸ä¿®æ¹äºåéä¸çå
容ï¼å
¶ä»çº¿ç¨é½è½æç¥å¹¶ä¸è½è¯»åå·²æ´æ¹è¿çå
容ï¼è¿å¯¹æ°æ®äº¤æ¢æ¥è¯´æ¯é常快æ·çï¼ä½æ¯ç±äºå¤çº¿ç¨çåå¨ï¼å¯¹äºåä¸ä¸ªåéå¯è½åå¨ä¸¤ä¸ªæ两个以ä¸ç线ç¨åæ¶ä¿®æ¹åéæå¨çå
åå
容ï¼åæ¶ååå¨å¤ä¸ªçº¿ç¨å¨åéå¨ä¿®æ¹çæ¶å»è¯»å该å
åå¼ï¼å¦æ没æ使ç¨ç¸åºçåæ¥æºå¶æ¥ä¿æ¤è¯¥å
åçè¯ï¼é£ä¹æ读åå°çæ°æ®å°æ¯ä¸å¯é¢ç¥çï¼çè³å¯è½å¯¼è´ç¨åºå´©æºã
å¦æéè¦å¨ä¸ä¸ªçº¿ç¨å
é¨çå个å½æ°è°ç¨é½è½è®¿é®ãä½å
¶å®çº¿ç¨ä¸è½è®¿é®çåéï¼è¿å°±éè¦æ°çæºå¶æ¥å®ç°ï¼æ们称ä¹ä¸ºStatic memory local to a thread (线ç¨å±é¨éæåé)ï¼åæ¶ä¹å¯ç§°ä¹ä¸ºçº¿ç¨ç¹ææ°æ®ï¼TSD: Thread-Specific Dataï¼æè
线ç¨å±é¨åå¨ï¼TLS: Thread-Local Storageï¼ãè¿ä¸ç±»åçæ°æ®ï¼å¨ç¨åºä¸æ¯ä¸ªçº¿ç¨é½ä¼åå«ç»´æ¤ä¸ä»½åéçå¯æ¬(copy)ï¼å¹¶ä¸é¿æåå¨äºè¯¥çº¿ç¨ä¸ï¼å¯¹æ¤ç±»åéçæä½ä¸å½±åå
¶ä»çº¿ç¨ãå¦ä¸å¾ï¼
äºãä¸æ¬¡æ§åå§å
å¨è®²è§£çº¿ç¨ç¹ææ°æ®ä¹åï¼å
让æ们æ¥äºè§£ä¸ä¸ä¸æ¬¡æ§åå§åãå¤çº¿ç¨ç¨åºææ¶æè¿æ ·çéæ±ï¼ä¸ç®¡å建å¤å°ä¸ªçº¿ç¨ï¼æäºæ°æ®çåå§ååªè½åçä¸æ¬¡ãåå¦ï¼å¨C++ç¨åºä¸æ个类å¨æ´ä¸ªè¿ç¨ççå½å¨æå
åªè½åå¨ä¸ä¸ªå®ä¾å¯¹è±¡ï¼å¨å¤çº¿ç¨çæ
åµä¸ï¼ä¸ºäºè½è®©è¯¥å¯¹è±¡è½å¤å®å
¨çåå§åï¼ä¸æ¬¡æ§åå§åæºå¶å°±æ¾å¾å°¤ä¸ºéè¦äºãââå¨è®¾è®¡æ¨¡å¼ä¸è¿ç§å®ç°å¸¸å¸¸è¢«ç§°ä¹ä¸ºåä¾æ¨¡å¼ï¼Singletonï¼ãLinuxä¸æä¾äºå¦ä¸å½æ°æ¥å®ç°ä¸æ¬¡æ§åå§åï¼
#include <pthread.h>
// Returns 0 on success, or a positive error number on error
int pthread_once (pthread_once_t *once_control, void (*init) (void));
å©ç¨åæ°once_controlçç¶æï¼å½æ°pthread_once()å¯ä»¥ç¡®ä¿æ 论æå¤å°ä¸ªçº¿ç¨è°ç¨å¤å°æ¬¡è¯¥å½æ°ï¼ä¹åªä¼æ§è¡ä¸æ¬¡ç±initææåçç±è°ç¨è
å®ä¹çå½æ°ãinitææåçå½æ°æ²¡æä»»ä½åæ°ï¼å½¢å¼å¦ä¸ï¼
void init (void)
{
// some variables initializtion in here
}
å¦å¤ï¼åæ°once_controlå¿
é¡»æ¯pthread_once_tç±»ååéçæéï¼æååå§å为PTHRAD_ONCE_INITçéæåéãå¨C++0x以åæä¾äºç±»ä¼¼åè½çå½æ°std::call_once ()ï¼ç¨æ³ä¸è¯¥å½æ°ç±»ä¼¼ã使ç¨å®ä¾è¯·åè
https://github.com/ApusApp/Swift/blob/master/swift/base/singleton.hppå®ç°ã
ä¸ã线ç¨å±é¨æ°æ®API
å¨Linuxä¸æä¾äºå¦ä¸å½æ°æ¥å¯¹çº¿ç¨å±é¨æ°æ®è¿è¡æä½
#include <pthread.h>
// Returns 0 on success, or a positive error number on error
int pthread_key_create (pthread_key_t *key, void (*destructor)(void *));
// Returns 0 on success, or a positive error number on error
int pthread_key_delete (pthread_key_t key);
// Returns 0 on success, or a positive error number on error
int pthread_setspecific (pthread_key_t key, const void *value);
// Returns pointer, or NULL if no thread-specific data is associated with key
void *pthread_getspecific (pthread_key_t key);
å½æ°pthread_key_create()为线ç¨å±é¨æ°æ®å建ä¸ä¸ªæ°é®ï¼å¹¶éè¿keyæåæ°å建çé®ç¼å²åºãå 为ææ线ç¨é½å¯ä»¥ä½¿ç¨è¿åçæ°é®ï¼æ以åæ°keyå¯ä»¥æ¯ä¸ä¸ªå
¨å±åéï¼å¨C++å¤çº¿ç¨ç¼ç¨ä¸ä¸è¬ä¸ä½¿ç¨å
¨å±åéï¼èæ¯ä½¿ç¨åç¬ç类对线ç¨å±é¨æ°æ®è¿è¡å°è£
ï¼æ¯ä¸ªåé使ç¨ä¸ä¸ªç¬ç«çpthread_key_tï¼ãdestructorææåçæ¯ä¸ä¸ªèªå®ä¹çå½æ°ï¼å
¶æ ¼å¼å¦ä¸ï¼
void Dest (void *value)
{
// Release storage pointed to by 'value'
}
åªè¦çº¿ç¨ç»æ¢æ¶ä¸keyå
³èçå¼ä¸ä¸ºNULLï¼ådestructorææçå½æ°å°ä¼èªå¨è¢«è°ç¨ãå¦æä¸ä¸ªçº¿ç¨ä¸æå¤ä¸ªçº¿ç¨å±é¨åå¨åéï¼é£ä¹å¯¹å个åéæ对åºçdestructorå½æ°çè°ç¨é¡ºåºæ¯ä¸ç¡®å®çï¼å æ¤ï¼æ¯ä¸ªåéçdestructorå½æ°ç设计åºè¯¥ç¸äºç¬ç«ã
å½æ°pthread_key_delete()并ä¸æ£æ¥å½åæ¯å¦æ线ç¨æ£å¨ä½¿ç¨è¯¥çº¿ç¨å±é¨æ°æ®åéï¼ä¹ä¸ä¼è°ç¨æ¸
çå½æ°destructorï¼èåªæ¯å°å
¶éæ¾ä»¥ä¾ä¸ä¸æ¬¡è°ç¨pthread_key_create()使ç¨ãå¨Linux线ç¨ä¸ï¼å®è¿ä¼å°ä¸ä¹ç¸å
³ç线ç¨æ°æ®é¡¹è®¾ç½®ä¸ºNULLã
ç±äºç³»ç»å¯¹æ¯ä¸ªè¿ç¨ä¸pthread_key_tç±»åç个æ°æ¯æéå¶çï¼æ以è¿ç¨ä¸å¹¶ä¸è½å建æ é个çpthread_key_tåéãLinuxä¸å¯ä»¥éè¿PTHREAD_KEY_MAXï¼å®ä¹äºlimits.hæ件ä¸ï¼æè
ç³»ç»è°ç¨sysconf(_SC_THREAD_KEYS_MAX)æ¥ç¡®å®å½åç³»ç»æå¤æ¯æå¤å°ä¸ªé®ãLinuxä¸é»è®¤æ¯1024个é®ï¼è¿å¯¹äºå¤§å¤æ°ç¨åºæ¥è¯´å·²ç»è¶³å¤äºãå¦æä¸ä¸ªçº¿ç¨ä¸æå¤ä¸ªçº¿ç¨å±é¨åå¨åéï¼é常å¯ä»¥å°è¿äºåéå°è£
å°ä¸ä¸ªæ°æ®ç»æä¸ï¼ç¶å使å°è£
åçæ°æ®ç»æä¸ä¸ä¸ªçº¿ç¨å±é¨åéç¸å
³èï¼è¿æ ·å°±è½åå°å¯¹é®å¼ç使ç¨ã
å½æ°pthread_setspecific()ç¨äºå°valueçå¯æ¬åå¨äºä¸æ°æ®ç»æä¸ï¼å¹¶å°å
¶ä¸è°ç¨çº¿ç¨ä»¥åkeyç¸å
³èãåæ°valueé常æåç±è°ç¨è
åé
çä¸åå
åï¼å½çº¿ç¨ç»æ¢æ¶ï¼ä¼å°è¯¥æéä½ä¸ºåæ°ä¼ éç»ä¸keyç¸å
³èçdestructorå½æ°ãå½çº¿ç¨è¢«å建æ¶ï¼ä¼å°ææç线ç¨å±é¨åå¨åéåå§å为NULLï¼å æ¤ç¬¬ä¸æ¬¡ä½¿ç¨æ¤ç±»åéåå¿
é¡»å
è°ç¨pthread_getspecific()å½æ°æ¥ç¡®è®¤æ¯å¦å·²ç»äºå¯¹åºçkeyç¸å
³èï¼å¦æ没æï¼é£ä¹pthread_getspecific()ä¼åé
ä¸åå
å并éè¿pthread_setspecific()å½æ°ä¿åæå该å
ååçæéã
åæ°valueçå¼ä¹å¯ä»¥ä¸æ¯ä¸ä¸ªæåè°ç¨è
åé
çå
ååºåï¼èæ¯ä»»ä½å¯ä»¥å¼ºå¶è½¬æ¢ä¸ºvoid*çåéå¼ï¼å¨è¿ç§æ
åµä¸ï¼å
åçpthread_key_create()å½æ°åºå°åæ°
destructor设置为NULL
å½æ°pthread_getspecific()æ£å¥½ä¸pthread_setspecific()ç¸åï¼å
¶æ¯å°pthread_setspecific()设置çvalueååºãå¨ä½¿ç¨ååºçå¼åæ好æ¯å°void*转æ¢æåå§æ°æ®ç±»åçæéã
åãæ·±å
¥ç解线ç¨å±é¨åå¨æºå¶
1. æ·±å
¥ç解线ç¨å±é¨åå¨çå®ç°æå©äºå¯¹å
¶APIç使ç¨ãå¨å
¸åçå®ç°ä¸å
å«ä»¥ä¸æ°ç»ï¼
ä¸ä¸ªå
¨å±ï¼è¿ç¨çº§å«ï¼çæ°ç»ï¼ç¨äºåæ¾çº¿ç¨å±é¨åå¨çé®å¼ä¿¡æ¯
pthread_key_create()è¿åçpthread_key_tç±»åå¼åªæ¯å¯¹å
¨å±æ°ç»çç´¢å¼ï¼è¯¥å
¨å±æ°ç»æ 记为pthread_keysï¼å
¶æ ¼å¼å¤§æ¦å¦ä¸ï¼
æ°ç»çæ¯ä¸ªå
ç´ é½æ¯ä¸ä¸ªå
å«ä¸¤ä¸ªå段çç»æï¼ç¬¬ä¸ä¸ªå段æ 记该æ°ç»å
ç´ æ¯å¦å¨ç¨ï¼ç¬¬äºä¸ªå段ç¨äºåæ¾é对æ¤é®ã线ç¨å±é¨åå¨åç解æå½æ°çä¸ä¸ªå¯æ¬ï¼å³destructorå½æ°ã
æ¯ä¸ªçº¿ç¨è¿å
å«ä¸ä¸ªæ°ç»ï¼åæ为æ¯ä¸ªçº¿ç¨åé
ç线ç¨ç¹ææ°æ®åçæéï¼éè¿è°ç¨pthread_setspecific()å½æ°æ¥åå¨çæéï¼å³åæ°ä¸çvalueï¼
2. å¨å¸¸è§çåå¨pthread_setspecific()å½æ°åæ°valueçå®ç°ä¸ï¼å¤§å¤æ°é½ç±»ä¼¼äºä¸å¾çå®ç°ãå¾ä¸å设pthread_keys[1]åé
ç»func1()å½æ°ï¼pthread API为æ¯ä¸ªå½æ°ç»´æ¤æå线ç¨å±é¨åå¨æ°æ®åçä¸ä¸ªæéæ°ç»ï¼å
¶ä¸æ¯ä¸ªæ°ç»å
ç´ é½ä¸å¾çº¿ç¨å±é¨æ°æ®é®çå®ç°(ä¸å¾)ä¸çå
¨å±pthread_keysä¸å
ç´ ä¸ä¸å¯¹åºã
äºãæ»ç»
使ç¨å
¨å±åéæè
éæåéæ¯å¯¼è´å¤çº¿ç¨ç¼ç¨ä¸é线ç¨å®å
¨ç常è§åå ãå¨å¤çº¿ç¨ç¨åºä¸ï¼ä¿éé线ç¨å®å
¨ç常ç¨æ段ä¹ä¸æ¯ä½¿ç¨äºæ¥éæ¥åä¿æ¤ï¼è¿ç§æ¹æ³å¸¦æ¥äºå¹¶åæ§è½ä¸éï¼åæ¶ä¹åªè½æä¸ä¸ªçº¿ç¨å¯¹æ°æ®è¿è¡è¯»åãå¦æç¨åºä¸è½é¿å
使ç¨å
¨å±åéæéæåéï¼é£ä¹è¿äºç¨åºå°±æ¯çº¿ç¨å®å
¨çï¼æ§è½ä¹å¯ä»¥å¾å°å¾å¤§çæåãå¦ææäºæ°æ®åªè½æä¸ä¸ªçº¿ç¨å¯ä»¥è®¿é®ï¼é£ä¹è¿ä¸ç±»æ°æ®å°±å¯ä»¥ä½¿ç¨çº¿ç¨å±é¨åå¨æºå¶æ¥å¤çï¼è½ç¶ä½¿ç¨è¿ç§æºå¶ä¼ç»ç¨åºæ§è¡æçä¸å¸¦æ¥ä¸å®çå½±åï¼ä½å¯¹äºä½¿ç¨éæºå¶æ¥è¯´ï¼è¿äºæ§è½å½±åå°å¯ä»¥å¿½ç¥ãLinux C++ç线ç¨å±é¨åå¨ç®åå®ç°å¯åè
https://github.com/ApusApp/Swift/blob/master/swift/base/threadlocal.hï¼æ´è¯¦ç»ä¸é«æçå®ç°å¯åèFacebookçfollyåºä¸çThreadLocalå®ç°ãæ´é«æ§è½ç线ç¨å±é¨åå¨æºå¶å°±æ¯ä½¿ç¨__threadï¼è¿å°å¨ä¸ä¸èä¸è®¨è®ºã