Continuando a nossa série de artigos traduzidos do site lazyfoo, iremos estender o conceito de semáforos visto no artigo anterior, e ver como bloquear os dados de forma mais eficiente.
Semáforos operam no nível do sistema operacional. Operações atômicas são uma maneira de bloquear os dados em um nível de CPU, mais eficiente. Aqui veremos como bloquear uma seção crítica usando spinlocks da CPU.
//Data access spin lock SDL_SpinLock gDataLock = 0; //The "data buffer" int gData = -1;
Ao invés de um semáforo vamos usar um spinlock para proteger nosso buffer de dados.
bool loadMedia() { //Loading success flag bool success = true; //Load splash texture if( !gSplashTexture.loadFromFile( "48_atomic_operations/splash.png" ) ) { printf( "Failed to load splash texture!\n" ); success = false; } return success; } void close() { //Free loaded images gSplashTexture.free(); //Destroy window SDL_DestroyRenderer( gRenderer ); SDL_DestroyWindow( gWindow ); gWindow = NULL; gRenderer = NULL; //Quit SDL subsystems IMG_Quit(); SDL_Quit(); }
Ao invés de semáforos, spinlocks não precisam ser alocados e desalocados.
int worker( void* data ) { printf( "%s starting...\n", data ); //Pre thread random seeding srand( SDL_GetTicks() ); //Work 5 times for( int i = 0; i < 5; ++i ) { //Wait randomly SDL_Delay( 16 + rand() % 32 ); //Lock SDL_AtomicLock( &gDataLock ); //Print pre work data printf( "%s gets %d\n", data, gData ); //"Work" gData = rand() % 256; //Print post work data printf( "%s sets %d\n\n", data, gData ); //Unlock SDL_AtomicUnlock( &gDataLock ); //Wait randomly SDL_Delay( 16 + rand() % 640 ); } printf( "%s finished!\n\n", data ); return 0; }
Here our critical section is protected by SDL_AtomicLock and SDL_AtomicUnlock.
In this case it may seem like semaphores and atomic locks are the same, but remember that semaphores can allow access beyond a single thread. Atomic operations are for when you want a strict locked/unlocked state.
Aqui, nossa seção seção crítica é protegida por SDL_AtomicLock e SDL_AtomicUnlock. Nesse caso, pode parecer que semáforos e bloqueios atômicos são a mesma coisa, mas lembre que semáforos podem permitir acesso além de uma única thread. Operações atômicas são úteis quando você quer um estado de bloqueio/desbloqueio mais preciso.
Baixe s arquivos de mídia e do código fonte desse tutorial aqui.