gcc 원자 연산을 사용하면 구성이 변경되었는지 (두 int를 비교할 시간) 새 구성을로드 할 수 있는지 신속하게 테스트 할 수 있습니다. 잠금없이 모두.
사이비 코드 :
내가 구성했다 구조체 C.가 보자 현재 설정을 가리키는 전역 변수 _pConfig 수 말할 수 있습니다. 우리는이 ... 각 스레드가 스레드로 구성된 C 구조체하는 PTR을 유지하기 위해 필요 어떻게 사용합니까 지금
// allocate a new struct C
struct C *pNewconfig = malloc(sizeof(struct C));
...
// load the pNewconfig struct from disk or something
...
// let the config struct have a next pointer so we can save list of configs for freeing later
pNewconfig->pNext = _pConfig;
// when done loading pNewconfig. change the global. not before done!, else threads see unf data!
// 32 bit assignment is atomic (usually).
// If not atomic on your platform, use __sync_bool_compare_and_swap()
_pConfig = pNewConfig;
// is safe to free old cfgs with 0 use counts. Make sure old is old enough so that there is no chance
// a thread could have been swapped out anywhere between point A and B below (next code section).
for (struct C *pCfg=pNewconfig->pNext ; pCfg ; pCfg=pCfg->pNext) {
// Free last pcfg (!pCfg->pNext) if its not in use and its old enough.
// Don't have to atomically check cUse here since once it changes to zero, its zero forever.
// nBirthday could be clock ticks when the config was created. nNow could be ticks now.
if (!pCfg->pNext && !pCfg->cUse && pCfg->nBirthDay-nNow > OldEnough) {
free(pCfg);
break;
}
}
:
struct C *_pConfig;
는 새로운 설정을로드합니다. _pConfig가 변경되면 각 스레드는 스레드의 구조체 C 주소를 현재 스레드와 비교하여 알 수 있습니다. pthread가 쓰레드의 데이타를 가리키는 포인터라고 가정한다.
while (1) {
// POINT A
struct C *pConfig = _pConfig; // make a copy in case it changes
// super quick check with no locking!
if (pConfig == pThread->pConfig)
break; // no change...get out quick.
__sync_add_and_fetch(&pConfig->cUse, 1); // increment use count of new cfg
// POINT B
__sync_sub_and_fetch(&pThread->pConfig->cUse, 1); // decriment use count of thread's cfg
pThread->pConfig = pConfig; // use new cfg
// do whatever you do with the cfg data
}
사용 __sync_add, 여러 스레드가 동시에 새로운 설정에 접근 할 수 있으며이 정확한 사용 수를 보장하기 때문에 _sub.
지점 A와 B 사이에 스케줄 된 스레드의 정지 시간을 알고 있어야합니다. 시간 조각은 일반적으로 1ms이므로 스케줄러가 닫히지 않는 한 긴 정지는 10-100ms가 될 수 있습니다. 구성 데이터가 작고 한 시간에 몇 번만 변경되는 경우, 며칠 동안 그것을 풀어 놓은 후에 해제 할 수 있습니다. 스톨 된 스레드가 없다는 것을 알 수있는 충분한 시간을 선택하십시오. 어떠한 이유로 든 스레드가 오랫동안 새로운 설정을 확인하지 않았다면 걱정하지 마십시오 ... 사용 횟수가 1보다 많아서 해제되지 않습니다.
이전 구성을 해제하기 전에 충분히 오래 기다리거나 참조 설정을 전혀 해제하지 않으면 참조 카운팅이 과장 될 수 있습니다. 이 솔루션의 중요한 개념은 새로운 구성 구조를 만들어 스레드가 변경 사항을 알기 전까지 이전의 스레드를 계속 사용할 수있게하는 것입니다. – johnnycrash