CS 241 System Programming More Timers, Signals Midterm reviewOutlineTimers: sigeventAlarm signal – sending SIGUSR1Starting/stopping timersa_sigaction (Section 9.4)Signal handler for multiple signalsTimers & threads: SIGEV_THREADTimer thread examplePassing values to signal handlersSlide 11ProcessesMemory LayoutForking processes (Chains & Fans)ThreadpThreadsSynchronization - reviewCPU SchedulingQueuing TheoryAnalysis of Single Server QueueQueuing ExampleResource allocation & Wait for GraphsSlide 23RecapCS 241 System ProgrammingMore Timers, SignalsMidterm reviewDiscussion Section 627 Feb – 2 MarOutlineSignals & Timers revisitedMidterm ReviewProcessesThreadsSynchronizationSchedulingTimers: sigeventPOSIX:TMR timers by default send SIGALRMUse struct sigevent to change this if neededstruct sigevent {int sigev_notify; /* notification type */int sigev_signo; /* signal number */union sigval sigev_value; /* signal value */}sigev_notifySIGEV_NONE - No notification from timerSIGEV_SIGNAL - Default: Send a signalSIGEV_THREAD - Create a new thread and run itunion sivalEither int sival_int or void* sival_ptrAlarm signal – sending SIGUSR1timer_t timerid;void createTimer(){struct sigevent se;se.sigev_signo = SIGUSR1; if (timer_create(CLOCK_REALTIME, &se, &timerid)==-1) { fprintf(stderr,"Failed to create timer\n”); exit(-1); }}Starting/stopping timervoid setTimer(int seconds){ struct itimerspec timervals; timervals.it_value.tv_sec = seconds; timervals.it_value.tv_nsec = 0; timervals.it_interval.tv_sec = seconds; timervals.it_interval.tv_nsec = 0; if (timer_settime(timerid, 0, &timervals, NULL) == -1) { fprintf(stderr,"Failed to start timer\n"); exit(-1); }}sa_sigaction (Section 9.4)char* code = NULL;switch (info->si_code){case SI_USER: code = "USER"; break;case SI_QUEUE: code = "QUEUE"; break;case SI_TIMER: code = "TIMER"; break;case SI_ASYNCIO: code = "ASYNCIO“; break;case SI_MESGQ: code = "MESGQ"; break;default: code = "Unknown"; break;}Signal handler for multiple signalsvoid signalCatcher(int signo, siginfo_t* info, void* context){char message[30];char* code = NULL;switch (info->si_code) { <..SNIP..from previous slide..> }fprintf(stderr, "Signal=%3d(%s), si_signo=%3d, si_code=%d(%s), si_value=%d\n", signo, getSignal(signo), info->si_signo, info->si_code, code, info>si_value.sival_int);/* Actual action depends on signal */switch (signo){case SIGQUIT /*Ctrl-|*/: setTimer(0); break; /* Stop timer */case SIGINT /*Ctrl-C*/: setTimer(1); break; /* Start timer */default: break;}}Timers & threads: SIGEV_THREADvoid createTimer() {struct Value* value = (struct Value*)malloc(sizeof(struct Value));value->a = 100;value->b = 100.001;struct sigevent se;se.sigev_signo = SIGUSR1;se.sigev_notify = SIGEV_THREAD;se.sigev_notify_function = threadfunc0;se.sigev_value.sival_ptr = (void*)value; if (timer_create(CLOCK_REALTIME, &se, &timerid)== -1) { fprintf(stderr,"Failed to create timer"); exit(-1); }fprintf(stderr, "Timer Created\n");}At each timer event, create a thread and run threadfunc0Timer thread examplevoid threadfunc0(union sigval sv){struct Value* value = (struct Value*)sv.sival_ptr;int mycounter = counter++;fprintf(stderr, "Running thread: %ud, counter = %d, value->a = %d, value->b = %f\n",pthread_self(), mycounter, value->a, value->b);int i;for (i = 0; i < 10; i++){ sleep (1); fprintf(stderr, "Running thread: %ud, counter = %d\n", pthread_self(), mycounter);}}Passing values to signal handlerskill – Sends a signal to a pidsigqueue – Queues & sends a signal with a value to a pidunion sigval value can be int or void*int main(int argc, char* argv[]){int pid = atoi(argv[1]);int signal = getSignal(argv[2]);int sendValue = atoi(argv[3]);kill(pid, signal); /* Send signal to pid */union sigval value;value.sival_int = sendValue;/* Queues & sends signal with value */sigqueue(pid, signal, value);}OutlineSignals & Timers revisitedMidterm ReviewProcessesThreadsSynchronizationSchedulingProcessesProcessInstance of a program (currently executing)Has alterable state, variables, memoryProcess IDStatesNewRunningBlockedReadyDoneContext SwitchesMemory LayoutForking processes (Chains & Fans)Process Chainfor (i = 1; i < n; i++) if (childpid = fork()) break;Process Fanfor (i = 1; i < n; i++) if ((childpid = fork()) <= 0) break;ThreadADT representing thread of execution within a processAvoids context switchesHas its own execution stack, program counter value, register set, and stateShare process address space & process resources“Lightweight process”pThreadsvoid* threadfunction(void* arg);POSIX function Descriptionpthread_cancelterminate another threadpthread_createcreate a threadpthread_detachset thread to release resourcespthread_equaltest two thread IDs for equalitypthread_exitexit a thread without exiting processpthread_killsend a signal to a threadpthread_joinwait for a threadpthread_selffind out own thread IDSynchronization - reviewAtomic operationsCritical sectionsMutual exclusionMutexSemaphoreConditional VariableRead-write locksCPU SchedulingAlgorithmsFirst-Come First-Serve (FCFS)Shortest Job First (SJF)Round Robin (RR)PriorityPreemptive & Non-preemptiveMetricsWaiting TimeTurnaround TimeQueuing Theory = arrival rateμ = service rateWq= mean time a customer spends in the queue W = mean time a customer spends in the systemLq = number of customers in queueL = number of customers in the systemLq = wqL = W ( Little's theorem)Analysis of Single Server Queue1WqW12qL•Server Utilization:•Time in System:•Time in Queue:•Number in Queue (Little):Queuing ExampleArrival 3 job/sec from StartArrival 2 jobs/sec from Event queueProcessor 1 services 2 jobs/secProcessor 2 services 4 jobs/secCompute the following:UtilizationTime in systemTime in queueLength of queueNow, what if processor 2 services 3 jobs/sec?Resource allocation & Wait for GraphsResource Allocation GraphResource allocation & Wait for GraphsResource Allocation Graph Corresponding Wait For GraphRecapSignals & TimersMidterm
View Full Document