I dagens värld har Busy-waiting blivit ett ämne för ständigt intresse och debatt. Oavsett om det är dess inverkan på samhället, dess historiska relevans eller dess inflytande på populärkulturen, drar Busy-waiting till sig uppmärksamhet från människor i alla åldrar, kön och bakgrunder. Genom åren har Busy-waiting genererat alla möjliga åsikter, teorier och tolkningar, och blivit ett centralt inslag på många områden. I den här artikeln kommer vi att utforska olika aspekter av Busy-waiting och dess betydelse i det samtida sammanhanget. Från dess ursprung till dess nuvarande återverkningar kommer vi att ta en djupgående titt på betydelsen av Busy-waiting i vår värld idag.
Busy-waiting, busy-looping eller spinning är en teknik där en process upprepade gånger kontrollerar om ett tillstånd gäller, exempelvis om en tangentbordsinmatning eller ett datorlås finns tillgängligt. Spinning kan även användas för att generera en godtycklig fördröjning, en teknik som var nödvändig på system som saknade en metod för att vänta en specifik tidslängd. Processorhastigheter varierar kraftigt mellan datorer, speciellt då en del processorer är utformade för att dynamiskt justera hastigheten baserat på externa faktorer, som exempelvis belastningen på operativsystemet. Därför kan spinning som en tidsfördröjningsteknik ofta producera oförutsägbara eller t.o.m. inkonsistenta resultat såvida koden är implementerad för att bestämma hur snabbt processorn kan köra en tom loop, eller om loopkoden kollar en realtidsklocka.
Spinning kan vara en bra strategi i vissa förhållanden, i synnerhet för implementationen av spinlock inom operativsystem som är byggda att köras på SMP-system. I allmänhet ses spinning som ett antimönster och bör undvikas då processortiden skulle kunna användas för att utföra en annan uppgift istället för att slösa på den på en meningslös aktivitet.
Följande kod skriven i C illustrerar två trådar som delar ett globalt heltal i. Den första tråden använder busy-waiting för att kolla efter en ändring i värdet för i:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
volatile int i = 0; /* i är global, så den är synlig för alla funktioner.
Den är även volatile, eftersom den
kanske ändras på ett sätt som kompilatorn inte kan förutspå,
här ifrån en annan tråd. */
/* f1 använder ett spinlock för att vänta på i att ska ändras från 0. */
static void *f1(void *p)
{
while (i==0) {
/* gör ingenting - fortsätt vänta om och om igen */
}
printf("i's value has changed to %d.\n", i);
return NULL;
}
static void *f2(void *p)
{
sleep(60); /* vila i 60 sekunder */
i = 99;
printf("t2 has changed the value of i to %d.\n", i);
return NULL;
}
int main()
{
int rc;
pthread_t t1, t2;
rc = pthread_create(&t1, NULL, f1, NULL);
if (rc != 0) {
fprintf(stderr,"pthread f1 failed\n");
return EXIT_FAILURE;
}
rc = pthread_create(&t2, NULL, f2, NULL);
if (rc != 0) {
fprintf(stderr,"pthread f2 failed\n");
return EXIT_FAILURE;
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
puts("All pthreads finished.");
return 0;
}
I ett fall som detta kan C11:s condition variable användas istället.