Operating Systems - Sync/Race Conditions - Test 2

Ace your homework & exams now with Quizwiz!

Semaphore Algorithm

#define Boolean int #define TRUE 1 #define FALSE 0 Shared variable:Semaphore mutex initialized to 1 P0: while(TRUE) { non-critical section wait(mutex); critical section signal(mutex); non-critical section } P1: while(TRUE) { non-critical section wait(mutex); critical section signal(mutex); non-critical section }

Semaphore

An abstract data type with a non-negative integer value, two valid atomic operations, apart from initialization with the following semantics: P/down/wait - value--; V/up/signal - value++;

Producer and Consumer problem

Circular buffer, count keeps track of no. of full buffers; incremented by producer after it produces an item and decremented by consumer after consuming an item.

Process Synchronization

Cooperating processes require an inter-process communication (IPC) mechanism to exchange information and data.

Race Condition

Cooperating processes, sharing same data structure can result in inconsistencies (race condition). Several processes access and manipulate same/shared data concurrently and outcome depends on particular order in which access takes place; usually due to preemptive process scheduling.

Counting semaphore

Counting semaphore are useful in controlling exclusive access to resources. The semaphore value is initialized to the number of instances of the resource available. The down and up operations correspond to resource acquisition and release, respectively.

Producer Process

while(TRUE) { ... produce an item in nextp // local variable ... while(count == BUFFER_SIZE); // do nothing; busy waiting buffer[in] = nextp; in = (in + 1) % BUFFER_SIZE; count = count + 1; .... }

Consumer Process

while(TRUE) { ... while(count == 0); // do nothing; busy waiting nextc = buffer[out]; out = (out + 1) % BUFFER_SIZE; count = count - 1; ... consume the next item in nextc; // local variable .... }

Producer Process with Semaphores

#define TRUE 1 #define FALSE 0 #define BUFFER_SIZE 100 //size of the buffer #define OBJTYPE ... //specify type here OBJTYPE buffer[BUFFER_SIZE]; //shared buffer int in = 0; //next free slot pointer int out = 0; //first full slot pointer int count = 0; //number of items in buffer semaphore mutex; //initialized to 1; binary Semaphore semaphore empty; //initialized to BUFFER-SIZE semaphore full; //initialized to 0 while (TRUE) { ... //non-critical section produce an item in nextp; //local variable ... //non-critical section wait (empty); wait (mutex); buffer [in] = nextp; in = (in + 1) % BUFFER_SIZE; count = count + 1; signal (mutex); signal (full); ... //non-critical section }

Consumer Process with Semaphores

#define TRUE 1 #define FALSE 0 #define BUFFER_SIZE 100 //size of the buffer #define OBJTYPE ... //specify type here OBJTYPE buffer[BUFFER_SIZE]; //shared buffer int in = 0; //next free slot pointer int out = 0; //first full slot pointer int count = 0; //number of items in buffer semaphore mutex; //initialized to 1; binary Semaphore semaphore empty; //initialized to BUFFER-SIZE semaphore full; //initialized to 0 while (TRUE) { ... //non-critical section wait (full); wait (mutex); nextc = buffer [out]; out = (out + 1) % BUFFER_SIZE; count = count - 1; signal (mutex); signal (empty); ... //non-critical section consume the item in nextc; //local variable ... //non-critical section }

Blocked Waiting

Busy waiting wastes CPU cycle time; blocked waiting is preferred (process put on waiting queue in waiting state and CPU selects another process to execute). Maintain a list of processes blocked on the semaphore; allow value to go negative to keep count of the number of processes waiting. Blocked process is restarted by a wakeup() and put on ready queue when some other process executes signal(). List of blocked processes may follow any queuing strategy e.g. LIFO, FIFO etc.

Peterson's Algorithm

If the other process wants to get in, let it in if it is it's turn. But if it doesn't want in, take its place. If turn == k, process k is allowed to enter its critical section. Process k will set flag[k]to TRUE if it wants to enter its critical section. #define Boolean int #define TRUE 1 #define FALSE 0 Shared variable: int turn -- initialized to 0 or 1 Boolean flag[2] -- Both initialized to FALSE P0: while(TRUE) { non-critical section flag[0] = TRUE; turn = 1; while(turn == 1 && flag[1] == TRUE); critical section flag[0] = FALSE; non-critical section } P1: while(TRUE) { non-critical section flag[1] = TRUE; turn = 0; while(turn == 0 && flag[0] == TRUE); critical section flag[1] = FALSE; non-critical section }

Solution to Critical-section problem must meet

Mutual Exclusion - If P1 is executing in its critical section, then no other processes can be executing in their critical sections. Progress - If no process is executing in its critical section and there exist some processes that wish to enter their critical section, then only those processes that want to enter can participate in the decision and the decision cannot be postponed indefinitely. Bounded Waiting - A bound must exist on the no. of times that other processes are allowed to enter their critical sections after a process has made a request to enter its critical section and before that request is granted (to prevent starvation).

Disabling Interrupts

No timer, no process switching, but dangerous, can be used by kernel processes, will not work in multicore and multiprocessor systems.

Structure for processes

P0: while(TRUE) { non-critical section entry section critical section exit section non-critical section } P1: while(TRUE) { non-critical section entry section critical section exit section non-critical section } Entry section: code implementing request to enter the critical section. Critical section: part of a process where it is manipulating shared memory. Exit section: may follow the critical section.

Critical Section

Part of a process where it is manipulating shard memory.

Shared Memory

Share memory to communicate between processes by creating shared memory (like any other memory).

Problem with the Produce and Consumer Code

The producer and consumer can concurrently execute the statements count++ and count-- resulting in incorrect values. Possible solutions: - count is shared and should be protected to avoid unpredictable race condition (output depends on order of execution) - only one process should be allowed to manipulate count at any time: need process synchronization and coordination.

Deadlock

Two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes.

Producer Consumer with Semaphores

Use semaphore mutex to ensure mutual exclusion in the critical sections. Use semaphore empty for producer synchronization. Use semaphore full for consumer synchronization.

Atomic Operations

When one process is accessing Semaphore S, until that operation is complete, no other process can access it. View the semaphore value as the number of tokens or available resources. The P/down/wait operation allows us to seize a token. The V/up/signal operation allows us to return a token. The value S can be any arbitrary non-negative integer. For a binary semaphore, the value s can only be 0 or 1.

Semaphore definition

typedef struct{ int value; struct process *list; } semaphore; Implementation of wait: wait(semaphore *S) { S->value--; if (S->value < 0) { add this process to S->list; block(); } } Implementation of signal: signal(semaphore *S) { S->value++; if (S->value <= 0) { remove a process P from S->list; wakeup(P); } }


Related study sets

Chapter 4: Mental Disorders and Suicide Test Study Guide

View Set

All About Boats - Stanley Francis

View Set

Nursing 2 - Our Solutions Training and Support JACQUELINEexpand_more CoursePoint+ Logo Lippincott CoursePoint+ for Honan: Focus on Adult Health: Medical-Surgical Nursing, Second Edition Nursing II SP 22

View Set

Unit 2 Week 2 Grammar- Singular and Plural Nouns

View Set

Chapter 11 AAPC Practical application

View Set