Download as pdf or txt
Download as pdf or txt
You are on page 1of 408

Java I/O

Оперативни системи 2020


Аудиториски вежби
Java I/O
 The Java Input/Output (I/O) is a part of the java.io
package.
 The java.io package contains a fairly large number of
classes that deal with Java input and output.
 The classes in the package are primarily abstract classes
and stream-oriented that define methods and subclasses
which allow data to be read from and written to files or
other input and output sources.
 InputStream and OutputStream are central classes in
the package which are used for reading from and writing
to byte streams, respectively.

2 Оперативни системи 2020


Аудиториски вежби
File System Facts
 What is a Path?
 Relative or Absolute?
 Symbolic Links

3 Оперативни системи 2020


Аудиториски вежби
The File Class
 Before getting into the classes that actually read and
write data to streams, we’ll look at a library utility that
assist you with file and directory manipulation.
 The File Class doesn’t refer to a file for input or output,
but it is used for manipulation of the file system that
holds the files and directories.

4 Оперативни системи 2020


Аудиториски вежби
The File Class operations
public String getName() public boolean canRead()

public String getParent() public boolean canWrite()

public String getPath() public boolean exists()

public long lastModified() public boolean isDirectory()

public long length() public boolean isFile()

public boolean delete() public boolean isHidden()

public String[] list() (FilenameFilter filter) public boolean setReadOnly()

public File[] listFiles() (FilenameFilter fil)

public boolean mkdir()

public boolean mkdirs()

public boolean renameTo(File dest)

public boolean setLastModified(long time)

5 Оперативни системи 2020


Аудиториски вежби
File Operations …

6 Оперативни системи 2020


Аудиториски вежби
… File Operations

7 Оперативни системи 2020


Аудиториски вежби
Directory Listing
 Suppose you want to see a directory listing.
 The File object can be used in two ways:
 for a full list of what the directory denoted by the File object
contains, use list() without arguments;
 for a restricted list, use a “directory filter”;

8 Оперативни системи 2020


Аудиториски вежби
Directory Listing – Example 1 …
 List the directory content, with or without a filter;

9 Оперативни системи 2020


Аудиториски вежби
… Directory Listing – Example 1
 List the directory content, with or without a filter;

10 Оперативни системи 2020


Аудиториски вежби
Directory Listing – Example 2
 Recursively list all subdirectories from a starting point in the file system,
and print the file permissions;

11 Оперативни системи 2020


Аудиториски вежби
Checking for and creating directories
 The File class is more than just a representation of an
existing file or directory.
 You can also use a File object to create a new directory
or an entire directory path if it doesn’t exist.
 The following example shows some of the other methods
available with the File class.

12 Оперативни системи 2020


Аудиториски вежби
Directory Manipulation – Example …

13 Оперативни системи 2020


Аудиториски вежби
… Directory Manipulation – Example …

14 Оперативни системи 2020


Аудиториски вежби
… Directory Manipulation – Example

15 Оперативни системи 2020


Аудиториски вежби
Input and Output
 The basic organization of the java.io classes, consisting of:
 Input and Output streams (byte oriented streams);
 Readers and Writers (character oriented streams);
 Data and Object I/O streams;

 An I/O Stream represents an input source or an output


destination.
 A stream can represent different kinds of sources and
destinations:
 disk files, devices, other programs, memory arrays
 A stream supports different kinds of data:
 simple bytes, primitive data types, localized characters, objects

16 Оперативни системи 2020


Аудиториски вежби
Input
 Reading information into a program

17 Оперативни системи 2020


Аудиториски вежби
Output
 Writing information from a program

18 Оперативни системи 2020


Аудиториски вежби
Input and Output
 Everything is derived from:
 InputStream and Reader
 Abstract classes which have basic methods called read(), used for
reading a single byte / char, or an array of bytes / chars;
 InputStream is used for reading input stream of bytes;

 Reader is used for reading character streams;

 OutputStream or Writer
 Abstract classes which have basic methods called write(), used for
writing a single byte / char, or an array of bytes / chars;
 OutputStream is used for writing output stream of bytes;

 Writer is used for writing character streams;

19 Оперативни системи 2020


Аудиториски вежби
Types of InputStream
 In the InputStream class, bytes can be read from
different sources:
 An array of bytes;
 A String object;
 A file;
 A pipe;
 A sequence of other streams, so you can collect them together
into a single stream;
 Other sources, such as an Internet connection;

20 Оперативни системи 2020


Аудиториски вежби
InputStream methods
 Various methods are included in the InputStream class:
 read() - reads a single byte, an array, or a subarray of bytes.
It returns the bytes read, the number of bytes read, or -1 if
end-of-file has been reached;
 skip() - which takes long, skips a specified number of bytes
of input and returns the number of bytes actually skipped;
 available() - returns the number of bytes that can be read
without blocking. Both the input and output can block threads
until the byte is read or written;
 close() - closes the input stream to free up system
resources;

21 Оперативни системи 2020


Аудиториски вежби
Types of InputStream
Class Function

Allows a buffer in memory to be used as an


ByteArrayInputStream
InputStream

StringBufferInputStream Converts a String into an InputStream

FileInputStream For reading information from a file

Produces the data that’s being written to the associated


PipedInputStream
PipedOutputStream. Implements the "piping" concept

Converts two or more InputStream objects into a single


SequenceInputStream
InputStream

Overrides all methods of InputStream with versions


FilterInputStream
that pass all requests to the contained input stream

22 Оперативни системи 2020


Аудиториски вежби
Types of OutputStream
 Bytes can be written to three different types of sinks:
 An array of bytes
 A file
 A pipe

23 Оперативни системи 2020


Аудиториски вежби
OutputStream methods
 The OutputStream class provides several methods:
 void write() - method writes an integer byte, a byte array or
subarray of bytes;
 void flush() - method forces any buffered output to be
written;
 void close() - method closes the stream and frees up system
resources;
 It is important to close your output files, because sometimes the
buffers do not get completely flushed and, as a consequence, the
write is not complete.

24 Оперативни системи 2020


Аудиториски вежби
Types of OutputStream
Class Function

Creates a buffer in memory. All the data that you send to


ByteArrayOutputStream
the stream is placed in this buffer

FileOutputStream For sending information to a file

Any information you write to this automatically ends up as


PipedOutputStream input for the associated PipedlnputStream. Implements
the "piping" concept

Simply overrides all methods of OutputStream with


FilterOutputStream versions that pass all requests to the underlying output
stream

25 Оперативни системи 2020


Аудиториски вежби
Reading from InputStream with
FilterInputStream
 FilterlnputStream classes allow reading different
types of primitive data, as well as String objects
 All the methods start with ‘read’, such as readByte(),
readFloat(), etc.
 FilterlnputStream classes can modify the way an
InputStream behaves internally:
 whether it’s buffered or unbuffered;
 whether it keeps track of the lines it’s reading;
 whether you can push back a single character;

26 Оперативни системи 2020


Аудиториски вежби
Types of FilterInputStream
Class Function

Used in concert with DataOutputStream, so you can read


DataInputStream primitives (int, char, long, etc.) from a stream in a
portable fashion

Use this to prevent a physical read every time you want


BufferedInputStream
more data

Keeps track of line numbers in the input stream; you can


LineNumberInputStream
call getLineNumber() and setLineNumber(int)

Has a one-byte pushback buffer so that you can push back


PushbackInputStream
the last character read

27 Оперативни системи 2020


Аудиториски вежби
Writing from OutputStream with
FilterOutputStream
 FilterOutputStream classes allow the user:
 to format each of the primitives types and String
objects onto a stream in such a way that any
DatalnputStream can read them;
 All the methods start with ‘write’, such as writeByte(),
writeFloat(), etc .
 to print all of the primitive data types and String
objects in a viewable format;

28 Оперативни системи 2020


Аудиториски вежби
Types of FilterOutputStream
Class Function
Used in concert with DataInputStream so you can write
DataOutputStream primitives (int, char, long, etc.) to a stream in a
portable fashion

For producing formatted output. While


PrintStream DataOutputStream handles the storage of data,
PrintStream handles display

Use this to prevent a physical write every time you send


BufferedOutputStream
a piece of data. You can call flush() to flush the buffer

29 Оперативни системи 2020


Аудиториски вежби
Readers and Writers
 What are Readers?
 Readers are character-based input streams that read Unicode
characters.
 What are Writers?
 Writers are character-based output streams that write
character bytes and turn Unicode into bytes.

 Input and output done with these character-based


streams automatically translates to and from the local
character set.

30 Оперативни системи 2020


Аудиториски вежби
Readers and Writers

Sources and Sinks


InputStream
OutputStream
FileInputStream
FileOutputStream
StringBufferInputString
ByteArrayInputStream
ByteArrayOutputStream
PipedInputStream
PipedOutputStream

31 Оперативни системи 2020


Аудиториски вежби
Modifying string behavior
Filters
FilterInputStream

FilterOutputStream

BufferedInputStream

BufferedOutputStream
DataInputString

PrintStream

LineNumberInputStream

StreamTokenizer
PushbackInputStream

32 Оперативни системи 2020


Аудиториски вежби
Typical uses of I/O Streams
 You can combine the I/O stream classes in many different
ways.
 But, you’ll probably just use a few combinations.
 The following examples can be used as a basic reference
for typical I/O usage:
 Buffered input file
 Input from memory
 Formatted memory input
 Basic file output
 Text file output shortcut
 Storing and recovering data
 Random access file

33 Оперативни системи 2020


Аудиториски вежби
Read and Write, byte by byte

34 Оперативни системи 2020


Аудиториски вежби
Most common InputStream Mistake ...

35 Оперативни системи 2020


Аудиториски вежби
... Most common InputStream Mistake

36 Оперативни системи 2020


Аудиториски вежби
Reading a Text File

37 Оперативни системи 2020


Аудиториски вежби
Reading from the Standard Input

38 Оперативни системи 2020


Аудиториски вежби
Write Text File & Text File Content Copy

39 Оперативни системи 2020


Аудиториски вежби
File Output with Line Numbers

40 Оперативни системи 2020


Аудиториски вежби
Storing and Retrieving Data

41 Оперативни системи 2020


Аудиториски вежби
Random Access File

42 Оперативни системи 2020


Аудиториски вежби
Redirecting Standard I/O

43 Оперативни системи 2020


Аудиториски вежби
Java Threading & Concurrency

Оперативни системи 2018


Аудиториски вежби
Concurrency
 Concurrency means simultaneous execution of several
tasks.
 Context:
 Multiple applications;
 Multiple processes within application;
 Multiple threads within process;
 Main issues:
 Mutual exclusion;
 (Condition) Synchronization;
 Deadlock;

2 Оперативни системи 2018


Аудиториски вежби
Concurrency: Multitasking Paradigm

3 Оперативни системи 2018


Аудиториски вежби
Concurrency: Multithreading Paradigm

4 Оперативни системи 2018


Аудиториски вежби
Main Issues
 Mutual exclusion
 Exclusive access to non-shareable, but shared resources.
 typical example: printer;
 “Locks” associated with resources.
 Usually short duration of an operation.
 Condition synchronization
 Usually related to “consumable” resources.
 typical example: the producer-consumer example;
 May imply a long (and repeated) wait.
 Requires structures for management of waiting tasks.

5 Оперативни системи 2018


Аудиториски вежби
Deadlock
 A set of processes is deadlock if each process in the set is
waiting for an event, that only another process in the set
can cause.
 Because all the processes are waiting, none of them will
ever cause any of the events that could wake up any
other member of the set, and all the processes continue
to wait forever.
 Practical example: the dining philosophers table.

6 Оперативни системи 2018


Аудиториски вежби
Process vs. Thread

7 Оперативни системи 2018


Аудиториски вежби
Thread Lifecycle

8 Оперативни системи 2018


Аудиториски вежби
Thread Lifecycle in Detail

9 Оперативни системи 2018


Аудиториски вежби
Thread Lifecycle in Detail

10 Оперативни системи 2018


Аудиториски вежби
Thread Lifecycle in Detail

11 Оперативни системи 2018


Аудиториски вежби
Java Threads Model
 Multiple threads within a process (JVM).
 Exclusion synchronization built into the language (each
object has a lock).
 Condition synchronization based on monitors.
 JVMs may exploit multiple processors.
 There is a default thread in each Java program which runs
the ‘main’ of the program.
 New threads can be created and started.
 Thread is an object itself in Java.
 Hierarchies of thread classes are possible.

12 Оперативни системи 2018


Аудиториски вежби
Java Threads: Thread Class
 Java provides the class package ex1;
java.lang.Thread whose method
run() is intended to contain the public class Main {
thread's main logic.
public static void main(String[] args) {
 A class T can be derived from T obj = new T();
Thread and override the run() obj.start();
//obj runs in parallel
method. Instances of T are //with the main thread
threads and can be started by }
calling the start() method of
class Thread. }

 The start() method calls run() class T extends Thread {


method – you should not run public void run() {
// thread's main logic
the method run() by yourself. }
 A thread terminates when its }
run() method terminates.

13 Оперативни системи 2018


Аудиториски вежби
Java Threads: Runnable Interface
 Due to single inheritance, a new public class Main2 {
mechanism is required when T
public static void main(String[] args) {
must inherit another class.
Runnable obj = new T2();
 The interface Runnable contains Thread tobj = new Thread(obj);
the run() method – Thread tobj.start();
// tobj runs in parallel
actually implements Runnable. // with the main thread
 A class T2 can then inherit from }
}
another class and implement
Runnable. class Base {}
 An instance of T2 is given as
class T2 extends Base implements
argument to a constructor of Runnable {
Thread, to create a Thread public void run() {
object. // thread's main logic
}
}

14 Оперативни системи 2018


Аудиториски вежби
General Java Thread Lifecycle
 Generate: a running thread (t0) generates a new thread:
 ta = new ThreadA1();
 Start: the running thread starts the new one:
 ta.start();
 Work: the JVM scheduler starts run().
 Die: run() method ends its work.

15 Оперативни системи 2018


Аудиториски вежби
Thread Execution Example
Main done Main done
A: 1 B: -1
A: 2 A: 1
A: 3 A: 2
A: 4 B: -2
A: 5 B: -3
A: 6 B: -4
A: 7 A: 3
A: 8 B: -5
B: -1 … (наизменично)
B: -2 B: -14
… A: 13
B: -14 B: -15
B: -15 A: 14
B: -16 B: -16
B: -17 A: 15
B: -18 B: -17
B: -19 A: 16
B: -20 B: -18
B done A: 17
A: 9 B: -19
A: 10
A: 18

B: -20
A: 17
A: 19
A: 18
B done
A: 19
A: 20
A: 20
A done
A done

16 Оперативни системи 2018


Аудиториски вежби
Ending Thread Execution
 An alive thread continues to be alive until:
 run() returns normally;
 run() returns abruptly;
 destroy() is invoked on thread;
 program terminates;
 When a thread's run() terminates, the thread does not
hold locks anymore.
 destroy() is drastic, does not release locks and some JVMs
do not implement it.
 Interruption is advisory.

17 Оперативни системи 2018


Аудиториски вежби
Interruption Threads
 A thread can interrupt another thread with the interrupt()
method. The interrupted thread uses interrupted() to test
and clear the interrupted state.
 Example:
 Thread 1 has:
thread2.interrupt();
 Thread 2 has:
while (!interrupted()) {
// normal execution
}
 Thread 2 is cancellable.

18 Оперативни системи 2018


Аудиториски вежби
Threads Working Together
 In a multithreaded
program, we almost
never know which
thread will finish first
(or when).
 Waiting for a thread
to complete is done
with the join()
method, from the
class Thread.

19 Оперативни системи 2018


Аудиториски вежби
Risks of Threads
 Safety Hazards (Correctness)
 In the absence of sufficient synchronization, the ordering of
operations in multiple threads is unpredictable and sometimes
surprising.
 Illustrates a common concurrency hazard called a race
condition.
 Liveness Hazards (Deadlock)
 A liveness failure occurs when an activity gets into a state such
that it is permanently unable to make forward progress.
 infinite loop;
 If thread A is waiting for a resource that thread B holds
exclusively, and B never releases it, A will wait forever.

20 Оперативни системи 2018


Аудиториски вежби
Risks of Threads
 Performance Hazards
 Poor service time, responsiveness, throughput, resource
consumption, or scalability
 Degree of runtime overhead
 Context switches
 Saving and restoring execution context, loss of locality, and CPU time spent
scheduling threads instead of running them
 When threads share data
 Synchronization mechanisms that can inhibit compiler optimizations, flush
or invalidate memory caches, and create synchronization traffic on the
shared memory bus

21 Оперативни системи 2018


Аудиториски вежби
Atomicity
 Execution of operation is atomic if either all of the
operations occur or none of them occur.
 Atomicity ensures serializability.
 A concurrent execution is serializable if the execution is
guaranteed to correspond to some serial execution of those
threads;
 Ensures predictable result of the operations;

22 Оперативни системи 2018


Аудиториски вежби
Atomicity
 Example: var ++
 Operations:
 Read the value of the var variable from its memory location into the
processors registers;
 Increment the value;
 Write the incremented value into the memory location of the
variable;
 More than one processor cycle!
 The process / thread can be switched after each of the previous
operations;
 Therefore, the ++ operation is not atomic, i.e. it has an unpredictable
result in a multithreaded environment;

23 Оперативни системи 2018


Аудиториски вежби
Race Condition
 A race condition occurs when more than one thread is performing a series
of actions on shared resources and several possible outcomes can exist
based on the order of the actions from each thread are performed.

24 Оперативни системи 2018


Аудиториски вежби
Race Condition
 Example: Printer Spooler

Process A 4

Process B

25 Оперативни системи 2018


Аудиториски вежби
Critical Regions and Mutual Exclusion
 A critical region is a part of the code from a
process/thread which accesses shared variables, shared
files, or other shared memory objects.
 With multiple processes/threads running in the system,
we need to provide access to the critical region to only
one of the processes/threads, at any given time.
 We call this mutual exclusion.

26 Оперативни системи 2018


Аудиториски вежби
Mutual Exclusion: Race Condition Solution
 Mutex
 Provides atomicity of one or more instructions;
 In Java, the java.util.concurrent.locks.Lock implementations act
as a mutex by the use of the following methods:
 lock()
 Acquires the lock.
 If the lock is not available, then the current thread becomes disabled for
thread scheduling purposes, and lies dormant until the lock has been
acquired.
 unlock()
 Releases the lock.

27 Оперативни системи 2018


Аудиториски вежби
Mutual Exclusion: Monitor
 The use of mutex is error prone, and relies on the
programmer discipline.
 Monitor
 Every object in Java contains a ‘monitor’
 used to provide mutual exclusion access to critical sections of code;
 Synchronized
 marking a method or code block as synchronized;
 Only one thread at a time is allowed to execute any critical
section of code for a particular monitor.

28 Оперативни системи 2018


Аудиториски вежби
Synchronized Example

29 Оперативни системи 2018


Аудиториски вежби
Synchronized Use-Case
SafeSequence a=new SafeSequence();
SafeSequence b=new SafeSequence();

 Case 1: Thread 1 calls a.getNext() and Thread 2 calls


b.getNext()
 The both threads use different instances, which are synchronized
with different monitors;
 There is no critical region in this case, and the execution of the
threads will be simultaneous (parallel execution);
 Case 2: Thread 1 and Thread 2 both call a.getNext()
 The both threads are waiting on a method synchronized by a same
monitor (the instance a), so the methods will be invoked one after
the other;
 There will be mutual exclusion in the critical region;
 However, the ordering of the execution can’t be predicted;

30 Оперативни системи 2018


Аудиториски вежби
Static Synchronized Example

31 Оперативни системи 2018


Аудиториски вежби
Static Synchronized Use-Case
SafeSequence a=new SafeSequence();
SafeSequence b=new SafeSequence():
 Case 1: Thread 1 calls a.getNext() and Thread 2 calls
b.getNext()
 The method getNext() is static, which means that it is same
for all instances, i.e. all instances will delegate to the call:
SafeSequence.getNext()
 The both threads are waiting on a method synchronized by a
same monitor (the SafeSequence.class monitor), so the
methods will be invoked one after the other in the separate
threads;
 There will be mutual exclusion in the critical region;
 However, the ordering of the execution can’t be predicted;

32 Оперативни системи 2018


Аудиториски вежби
Synchronization
 Dependencies among the operations in different threads
 One thread should wait for the result of the other thread;
 Semaphores
 The java java.util.concurrent.Semaphore class.
 Conceptually, a semaphore maintains a set of permits.
 Each Semaphore.acquire() call blocks if necessary, until a
permit is available, and then takes it.
 Each Semaphore.release() call adds a permit, potentially
releasing a blocking acquirer.
 Often used to restrict the number of threads that can access
some (physical or logical) resource.
 Therefore, a mutex is sometimes referred to as a binary semaphore.

33 Оперативни системи 2018


Аудиториски вежби
Semaphore Example (not complete)
 Semaphore initialization
Semaphore empty = new Semaphore(1);

 Thread 1 – Producer
empty.acquire();
putItems(buffer);

 Thread 2 – Consumer
if(noMoreItems()) {
empty.release();
}
Item = getItem(buffer);

34 Оперативни системи 2018


Аудиториски вежби
Deadlock
 Mutual exclusion
 Resource can be assigned to at most one thread;
 Hold and wait
 Threads both hold some resource and request other resource;
 Circular wait
 A cycle exists in which each thread waits for a resource that is
assigned to another thread;

35 Оперативни системи 2018


Аудиториски вежби
Прашања?

36 Оперативни системи 2018


Аудиториски вежби
Синхронизација на повеќе процеси:
Race Conditions & Deadlock
Оперативни системи 2018
Аудиториски вежби
Analogy

Computer Systems Restaurant

 Program code  Recipe


 Resources  Fridge
 Objects (String, Integer, …)  Items (Milk, eggs, …)
 References (memory locat.)  Position (first shelf, left)
 Process/Thread  Chef
 The process (thread) is  The chef is executing the
executing the program recipe instructions, which
code, which references refer to the fridge items.
the resources.
2 Оперативни системи 2018
Аудиториски вежби
Multithreading scenario with shared resources
 Multiple threads can  Multiple chefs can cook by
execute the same code, the same recipe, using the
over the shared resources items from same fridge

3 Оперативни системи 2018


Аудиториски вежби
Identify Race Condition in Java
 Every object that is accessed from multiple threads
should be protected from a race condition.
 Method’s local variables are visible only to the thread that
executes the method, and shouldn’t be protected;
public class Test {
private static String staticField; // can be shared
private String classField; // can be shared
public String example() {
String localVariable=“something”; // never shared
}
public String example(String mayBeShared) {
String shouldBeProtected = mayBeShared;
}
}
4 Оперативни системи 2018
Аудиториски вежби
Identify Race Condition in Java
class Incrementer {
private int x;
public Incrementer(int i) { x=i; }
public void increment() { x++; }
}
private static Incrementer shared=new Incrementer(1);
Thread t=new Thread() {
private int threadLocal=0;
public void run() {
threadLocal++; // should not be synchronized
shared.increment(); // executed by every thread
// every thread is changing the value of x,
// even though it is private
}
}
5 Оперативни системи 2018
Аудиториски вежби
Identify Race Condition in Java
class Composite {
private Composite c; int x;
public Composite(int b) { x=b; }
public Composite(Composite a, int b) { c=a; x=b; }
public void move() { if(c!=null) c.move(); x++; }
}
private static Composite shared=new Composite(1);
Thread t=new Thread() {
public void run() {
Composite local = new Composite(shared, 1);
// should be synchronized, because of ‘shared’
local.move();
}
}

6 Оперативни системи 2018


Аудиториски вежби
Scope and Race Condition

7 Оперативни системи 2018


Аудиториски вежби
Scope and Race Condition

8 Оперативни системи 2018


Аудиториски вежби
Testing Scenario

9 Оперативни системи 2018


Аудиториски вежби
Reference vs. Primitive Values
 When invoking methods:
 values of the arguments from primitive types are copied into
local variables;
 arguments that are not primitive are passed as references, and
thus the actual object is shared among the threads;

10 Оперативни системи 2018


Аудиториски вежби
Private Fields are Safe, UNLESS they are shared
(leaked)

11 Оперативни системи 2018


Аудиториски вежби
Are Public Fields Safe?

12 Оперативни системи 2018


Аудиториски вежби
Shared Objects are not Safe!

13 Оперативни системи 2018


Аудиториски вежби
Test Output
 Total 103 mismatches
 2 public mismatches [forceSwitch(10)]
 The public field is modified only by the containing ExampleThread and
the main thread;
 101 shared object mismatches [forceSwitch(3)]
 100 ExampleThreads and the main thread are modifying the wrapper;
 Part of the output: [public-50] 1
[private-35] 1
[public-69] 1
public-mismatch-30
wrapper-mismatch-82
[wrapper-31] 103
[public-69] 2
[wrapper-69] 104
[public-20] 1
wrapper-mismatch-24
wrapper-mismatch-66
wrapper-mismatch-17
14 Оперативни системи 2018
Аудиториски вежби
Behind the Scene

15 Оперативни системи 2018


Аудиториски вежби
Protecting Class Fields

16 Оперативни системи 2018


Аудиториски вежби
Protecting Shared Objects (is there a difference?)

17 Оперативни системи 2018


Аудиториски вежби
Conditional Locking: Race Condition

Thread 1: Thread 2:

If(5<=5) // pause
// pause If(5<=5)
// pause val=5+1
val=6+1 // done

18 Оперативни системи 2018


Аудиториски вежби
Conditional Locking: DEADLOCK

Thread 1: Thread 2: Thread 3:


// lock // try lock // try lock
If(5<=5) // pause // pause
val=5+1 // pause // pause
// unlock // pause // lock
// done // pause If(6<=5)
// pause // done
// pause
……

19 Оперативни системи 2018


Аудиториски вежби
Conditional Locking: As it Should Be

20 Оперативни системи 2018


Аудиториски вежби
Conditional Deadlock

Thread 1: Thread 2..N:


// lock // try lock
If(5<=5) // pause
val=5+1 // pause
// wait x // pause

21 Оперативни системи 2018


Аудиториски вежби
Conditional Deadlock: Fixed

22 Оперативни системи 2018


Аудиториски вежби
Circular Deadlock (Simplified Example)

23 Оперативни системи 2018


Аудиториски вежби
Deadlock Solution
 Check the semaphore initialization
 If the initial conditions are not fixed

 Check the scenario


 Reorder the locks
 Check the conditions when lock occurs

24 Оперативни системи 2018


Аудиториски вежби
Scheduler Dependent Deadlock
 Think twice before blocking inside a synchronized block.
 Make sure that the unlock call (resA.release()) call is not
inside a synchronized block with the same monitor;

25 Оперативни системи 2018


Аудиториски вежби
Scheduler Dependent Deadlock: Fix

26 Оперативни системи 2018


Аудиториски вежби
Producer – Consumer
 Да се имплементира синхронизација на проблемот со
произведувач и потрошувач. Притоа, имаме еден
произведувач кој поставува ставки во бафер и
произволен број на потрошувачи кои паралелно ги
земаат поставените ставки.
 Иницијално баферот е празен.

27 Оперативни системи 2018


Аудиториски вежби
Producer – Consumer (Scenario)
 Произведувачот врши полнење на баферот со користење
на функцијата state.fillBuffer();
 Потрошувачот ја зема ставката наменета за него со
методот state.getItem(int id);
 Потрошувачот ја зема само ставката наменета за него, по што
чека ново полнење на баферот.
 По земањето на ставката од баферот, потрошувачот треба
повика state.decrementNumberOfItemsLeft() за да каже
дека ја земал ставката.
 Потрошувачот кој ќе ја земе последната ставка (го
оставил баферот празен) му сигнализира на
произведувачот за да го наполни баферот.
 За проверка дали баферот е празен да се користи
state.isBufferEmpty();

28 Оперативни системи 2018


Аудиториски вежби
Producer – Consumer (Constraints)
 Треба да се овозможи повеќе потрошувачи паралелно
да може да си ја земат својата ставка од баферот.
 Паралелно повикување на state.getItem(int id);
 Не смее да се повика state.getItem(int id)
доколку соодветната ставка претходно е земена и не е
поставена.
 Не смее да се повика state.fillBuffer() доколку
има ставки во баферот.
 Повиците state.isBufferEmpty() и
state.decrementNumberOfItemsLeft() го
модифицираат тековниот број на ставки во баферот.

29 Оперативни системи 2018


Аудиториски вежби
Producer – Consumer
 Да се имплементираат методите init(),
Producer.execute() и Consumer.execute(), при
што ќе се изведе синхронизација за да се
извршуваат според дефинираните услови.
 При извршувањето има една инстанца од Producer
и повеќе инстанци од Consumer класата кои се
извршуваат паралелно.
 Претпоставете дека методот execute() и кај двете
класи се повикува во бесконечна while јамка.
 Решение:
 Кодот е поставен на курсот

30 Оперативни системи 2018


Аудиториски вежби
Прашања?

31 Оперативни системи 2018


Аудиториски вежби
Синхронизација на повеќе процеси:
Задачи
Оперативни системи 2020
Аудиториски вежби
Задача: Producer – Controller
 Проблем: Producer – Controller, со ограничен број
проверки.
 Потребно е да направите оптимизација на
додавањата и проверките на податоците од одреден
бафер според следните услови:
 Кога се додава податок во баферот, во истиот момент:
 Не може да има додавање на други податоци
 Не може да се прави проверка на податоци
 Кога се прави проверка на податоци, во истиот
момент:
 Може да има максимум 10 активни проверки
 Не може да има додавање пред да завршат сите започнати
проверки
 Иницијално во баферот има податоци.
2 Оперативни системи 2020
Аудиториски вежби
Задача: Producer – Controller
 Баферот е претставен со инстанцата buffer од класата
Buffer. Притоа може да ги користите следните
методи:
 state.produce()
 Додава елемент во баферот.
 Фрла RuntimeException со соодветна порака доколку во истиот
момент се врши додавање или проверка на друг податок.
 state.check()
 Врши проверка на податок од баферот.
 Проверува дали во истиот момент се врши додавање или
паралелна проверка на повеќе од 10 податоци.

3 Оперативни системи 2020


Аудиториски вежби
Задача: Producer – Controller
 Имплементирајте ги методите execute() од класата Producer и
Controller, кои ќе функционираат според претходните
правила.
 Тие треба да ги користат методите state.produce() и
state.check() за додавање и проверка на податоци од
баферот, соодветно.
 Сите семафори и глобални променливи треба да ги дефинирате
самите, а нивната иницијализација да ја направите во методот
init().
 При имплементацијата на методите, не смеете да додадете try-
catch блокови во методите. (Важно при тестирањето)
 При извршувањето има повеќе инстанци од класите Producer и
Controller, кои вршат повеќе од едно додавање и проверка,
соодветно.
 Додавањата и проверките се стартуваат (скоро) истовремено и
паралелно се извршуваат.

4 Оперативни системи 2020


Аудиториски вежби
Решение I: Initialization

5 Оперативни системи 2020


Аудиториски вежби
Решение I: execute() methods

6 Оперативни системи 2020


Аудиториски вежби
Решение II: Initialization

7 Оперативни системи 2020


Аудиториски вежби
Решение II: execute() methods

8 Оперативни системи 2020


Аудиториски вежби
Задача: SiO2
 Во процесот на производство на EPROM меморија,
потребен е слој на силициум диоксид (SiO2).
 За да се формира оксидниот слој потребно е во ист
момент да бидат присутни два атоми на кислород и
еден атом на силициум.
 Со користење на семафори напишете програма која ќе
помогне во процесот на производство на EPROM
меморија.

9 Оперативни системи 2020


Аудиториски вежби
Задача: SiO2
 Секој од атомите е посебен процес.
 Силициумовите атоми (процеси) го извршуваат
методот proc_Si(), а кислородните атоми методот
proc_O().
 Откако ќе „се сретнат“ сите три атоми, секој од нив го
повикува виртуелниот метод bond(), за да се формира
SiO2.

10 Оперативни системи 2020


Аудиториски вежби
Задача: SiO2
 Ограничувања:
 Доколку до “бариерата” пристигне атом на силициум,
истиот мора да чека да се соберат два атоми на
кислород.
 Доколку пристигне атом на кислород, мора да чека на
еден атом на силициум и еден атом на кислород.
 Бариерата треба да ја напушти еден атом на силициум
и два атоми на кислород, кои формираат молекул на
силициум диоксид (SiO2).

11 Оперативни системи 2020


Аудиториски вежби
Решение (дискусија):
 Поставување на семафорите:
 Семафор кој што ќе врши контрола на атомот за силициум
Semaphore si = new Semaphore(1);
 Семафор кој што ќе врши контрола на двата атоми на
кислород (поради тоа што бројот на дозволи е 2, тоа значи
дека може да се направат максимум 2 повици на acquire())
Semaphore o = new Semaphore(2);
 Семафор кој што ќе врши контрола за тоа дали дошол атом на
силициум (кислород) до бариерата (поради тоа што истиот е
поставен на 0, тоа значи дека при повик на функцијата
acquire() прва, ќе настане блокирање, па мора да се
направи барем еден release() за да бројот на дозволи
стане 1 )
Semaphore siHere = new Semaphore(0);
Semaphore oHere = new Semaphore(0);
 Семафор кој врши контрола на бариерата
Semaphore ready = new Semaphore(0);
12 Оперативни системи 2020
Аудиториски вежби
Решение I:
 Имплементација на методот proc_Si():
proc_Si() {
si.acquire(); // дозволува само едeн атом на Si
siHere.release(); // notify the first O atom for the arrival
siHere.release(); // notify the second O atom for the arrival
oHere.acquire(); // wait for the first O atom
oHere.acquire(); // wait for the second O atom

// all the atoms needed are here


ready.release(); // for the first O atom
ready.release(); // for the second O atom
bond(); // create the molecule
si.release(); // another Si atom can bond now
}

13 Оперативни системи 2020


Аудиториски вежби
Решение I:
 Имплементација на методот proc_O():

proc_O() {
o.acquire(); // Only two atoms can interact simultaneously
siHere.acquire(); // wait for the Si atom to arrive
oHere.release(); // Notify that an O atom is here
ready.acquire(); // Wait for the ready signal
bond();
o.release(); // The process is done
}

14 Оперативни системи 2020


Аудиториски вежби
Решение II:
 Имплементација на методот proc_Si():
proc_Si() {
si.acquire(); // дозволува само едeн атом на Si
oHere.acquire(2); // wait for the O atoms

// all the atoms needed are here


ready.release(2); // for the first O atom
bond(); // create the molecule
si.release(); // another Si atom can bond now
}

15 Оперативни системи 2020


Аудиториски вежби
Решение II:
 Имплементација на методот proc_O():

proc_O() {
o.acquire(); // Only two atoms can interact simultaneously
oHere.release(); // Notify that an O atom is here
ready.acquire(); // Wait for the ready signal
bond();
o.release(); // The process is done
}

16 Оперативни системи 2020


Аудиториски вежби
Задача: Синхронизација на тоалет
 Во рамките на еден универзитет, за наставниот кадар се
воведуваат заеднички тоалети во кои е дозволен влез и за
жени и за мажи, според следните правила:
 доколку во тоалетот има жена, дозволен е влез за други жени, но
не и за мажи, и обратно (кога има маж, само други мажи може
да влегуваат).
 На влезот од тоалетот има лизгачки знак кој кажува во која
состојба се наоѓа тоалетот:
 празен, жена внатре, маж внатре.
 За опишаната ситуација да се напишат следните
процедури:
 zena_vleguva();
 zena_izleguva();
 maz_vleguva();
 maz_izleguva();

17 Оперативни системи 2020


Аудиториски вежби
Задача: Синхронизација на тоалет
 Може да се користат бројачи и техники за
синхронизација по желба.
 За кога некој влегува во тоалетот треба да се
повика wc.vlezi(), а кога некој излегува, да се
повика wc.izlezi(). Променливата wc е веќе
дефинирана.
 методите vlezi() и izlezi() не се атомични и треба да се
погрижите за нивна синхронизација.
 При извршувањето има многу мажи и жени
(паралелни нитки) кои се обидуваат да пристапат до
тоалетот.

18 Оперативни системи 2020


Аудиториски вежби
Решение:
Semaphore toalet = new Semaphore(1);
final Object mLock = new Object();
final Object zLock = new Object();
int maziVnatre = 0, zeniVnatre = 0; // глобални променливи

maz_vleguva() {
synchronized (mLock) {
if (maziVnatre == 0) {
toalet.acquire(); // тоалетот се поставува на зафатен
}
maziVnatre++;
wc.vlezi();
}
}

19 Оперативни системи 2020


Аудиториски вежби
Решение:
maz_izleguva() {
synchronized (mLock) {
wc.izlezi();
maziVnatre--;
if (maziVnatre == 0) {
toalet.release(); // тоалетот е слободен
}
}
}

20 Оперативни системи 2020


Аудиториски вежби
Решение:
zena_vleguva() {
synchronized (zLock) {
if (zeniVnatre == 0) {
toalet.acquire(); // тоалетот е зафатен
}
zeniVnatre++;
wc.vlezi();
}
}

21 Оперативни системи 2020


Аудиториски вежби
Решение:
zena_izleguva() {
synchronized (zLock) {
wc.izlezi();
zeniVnatre--;
if (zeniVnatre == 0) {
toalet.release(); // тоалетот се ослободува
}
}
}

22 Оперативни системи 2020


Аудиториски вежби
Задача: Уписи на ФИНКИ
 Во процесот на запишување студенти на еден факултет,
запишувањето го изведуваат обучени членови на
Конкурсната комисија, кои ги запишуваат
заинтересираните кандидати.
 На денот на запишувањето има една просторија на
располагање во која истовремено можат да работат
најмногу 4 членови на Комисијата.
 Секој член од Комисијата запишува 10 кандидати, еден по
еден, по што ја напушта просторијата и остава можност да
влезе нов член на Комисијата.
 Еден кандидат се опслужува само од еден од членовите на
Комисијата.
 Еден член на Комисијата може да опслужува само еден
кандидат во даден временски момент.

23 Оперативни системи 2020


Аудиториски вежби
Задача: Уписи на ФИНКИ
 Кога кај еден член на комисија е присутен еден кандидат,
членот на Комисијата го прави запишувањето со повик на
виртуелниот метод zapishi(). Пред да се запише,
студентот мора да го повика методот ostaviDokumenti(). За
време на извршување на овој метод, кандидатот мора да
биде присутен во просторијата. Потоа е слободен.
 Со користење на семафори, напишете програма која ќе
помогне во процесот на запишување студенти.
 Секој член на Комисијата претставува посебен thread во системот
и секој студент исто така претставува посебен thread.
 Членовите на Комисијата го извршуваат методот
komisijaUpis(), а кандидатите методот studentUpis().
 Напишете ги двата метода: komisijaUpis() и studentUpis().

24 Оперативни системи 2020


Аудиториски вежби
Решение:
Semaphore slobodnoUpisnoMesto = new Semaphore(4);
Semaphore studentEnter = new Semaphore(0);
Semaphore studentHere = new Semaphore(0);
Semaphore studentDone = new Semaphore(0);

komisijaUpis() {
slobodnoUpisnoMesto.acquire(); //cekame da se oslobodi mesto za komisijata

int i=NUM_STUDENTS; //go inicijalizirame brojot na studenti koi treba da


//bidat upisani od kandidatot od komisijata. (LOKALNA PROMENLIVA)

while(i>0){
studentEnter.release(); //Kazuvame deka moze da vleze student
studentHere.acquire(); //Cekame studentot da gi ostavi dokumentite
//i da ni signalizira deka e ovde
zapishi(); //Go zapisuvame studentot
studentDone.release(); //Kazuvame deka e upisan i moze da zamine
i--; //Go namaluvame brojot na preostanati
studenti
}
slobodnoUpisnoMesto.release(); //stom sme upisale 10 studenti, zaminuvame
}

25 Оперативни системи 2020


Аудиториски вежби
Решение:
studentUpis() {
studentEnter.acquire(); //studentot ceka da bide povikan
ostaviDokumenti();
studentHere.release(); //kazuva deka e ovde (gi ostavil
dokumentite)
studentDone.acquire(); //cekame da bide zapisan
//studentot e zapisan
}

26 Оперативни системи 2020


Аудиториски вежби
Задача: Синхронизација на пушачи
 Во една соба има 3 пушачи и еден агент. Секој пушач витка
цигара и ја пуши според следниве правила:
 За да ја свитка и испуши цигарата потребни му се 3 состојки:
тутун, ризла и кибрит.
 Eдниот од пушачите има неограничена количина на тутун,
другиот неограничена количина на ризли, додека, пак, третиот
неограничена количина на кибрит.
 Агентот има неограничена количина од трите состојки.
 Процесот е следен:
 Еден агент по случаен избор одбира 2 различни состојки и ги
става на маса.
 Пушачот кој ја има останатата состојка ја прави и пуши цигарата.
 Откако ќе ја испуши цигарата му сигнализира на агентот дека
може да стави нови две состојки на масата.
 Процесот се повторува од почеток.
 Иницијално масата е празна.
27 Оперативни системи 2020
Аудиториски вежби
Решение:

28 Оперативни системи 2020


Аудиториски вежби
Решение:

29 Оперативни системи 2020


Аудиториски вежби
Прашања?

30 Оперативни системи 2020


Аудиториски вежби
Java Networking

Оперативни системи 2020


Аудиториски вежби
Introduction
} Java’s networking support is a concept of socket. A socket
identifies an endpoint in a network.
} Socket communication takes place via a protocol. Internet
Protocol (IP) is a low-level routing protocol that breaks data into
small packets and sends them to an address across a network.
} Transmission Control Protocol (TCP) is a higher-level protocol that
manages to robustly string together these packets, sorting and
retransmitting them as necessary to reliably transmit data.
} User Datagram Protocol (UDP) is an alternative
communications protocol to Transmission Control Protocol (TCP)
used primarily for establishing low-latency and loss-tolerating
connections between applications on the internet.

2 Оперативни системи 2019


Аудиториски вежби
Networking basics
} Internet protocol (IP) addresses
} Every host on Internet has a unique IP address
} 143.89.40.46, 203.184.197.198
} More convenient to refer to using hostname string
} cs.ust.hk, tom.com, localhost
} Ports
} Many different services can be running on the host
} A port identifies a service within a host
} IP address + port number = "phone number“ for service

3 Оперативни системи 2019


Аудиториски вежби
Networking basics
} protocols : rules that facilitate communications between
machines
} Client-Server interaction
} Communication between hosts is two-way, but usually the two
hosts take different roles
} Server waits for client to make request
} Server registered on a known port with the host ("public
phone number")
} Usually running in endless loop
} Listens for incoming client connections

4 Оперативни системи 2019


Аудиториски вежби
Java Socket programming
} The term socket programming refers to writing programs that
execute across multiple computers in which the devices are all
connected to each other using a network.
} Java supports TCP/IP both by extending the already established
stream I/O interface.
} Java supports both the TCP and UDP protocol families.
} TCP is used for reliable stream-based I/O across the network.
} UDP supports a simpler, hence faster, point-to-point datagram-oriented
model.
} java.net.InetAddress class converts between
hostnames and internet addresses

5 Оперативни системи 2019


Аудиториски вежби
The Networking Classes and Interfaces
} Java provides a collection of classes and interfaces
that take care of low-level communication details
between the client and the server.
} import java.net.*;
Class Description
SocketServer This class implements server sockets.
This class implements client sockets (also
Socket
called just "sockets").
This class represents an Internet Protocol
InetAddress
(IP) address.
This class represents a socket for sending
DatagramSocket
and receiving datagram packets.
DatagramPacket This class represents a datagram packet.
6 Оперативни системи 2019
Аудиториски вежби
TCP Server

7 Оперативни системи 2019


Аудиториски вежби
TCP Client

8 Оперативни системи 2019


Аудиториски вежби
UDP Server

9 Оперативни системи 2019


Аудиториски вежби
UDP Client

10 Оперативни системи 2019


Аудиториски вежби
Questions?

11 Оперативни системи 2019


Аудиториски вежби
Процеси
Проф. Д-р Димитар Трајанов
Вон. проф. Д-р Невена Ацковска
Вон. проф. Д-р Боро Јакимовски
Вон. проф. Д-р Весна Димитрова
Доц. Д-р Игор Мишковски
Доц. Д-р Сашо Граматиков
 Процеси се програми во извршување

 Основна апстракција на ОС!


◦ Овозможуваат системи со еден CPU да му
делуваат на корисникот како системи со повеќе
(виртуелни) CPU
 Во секој миг паралелно работат повеќе
процеси
◦ ОС стартувани процеси
◦ Кориснички стартувани процеси

 Корисникот има илузија дека се извршуваат


паралелно
 Илузија на паралелно извршување на
повеќе процеси на еден CPU
◦ На секој од процесите му се дава одредено
време на CPU

 Креаторите на ОС направиле концептуален


модел на секвенционални процеси
а) Мултипрограмирање за четири процеси
b) Концептуален модел за 4 независни секвенцијални процеси
c) Само еден процес е активен во даден момент

A. S. Tanenbaum, Modern Operating Systems, 3rd


Edition, Pearson Prentice Hall, 2009

5
Настани кои доведуваат до креирање на процеси
1. Иницијализација на системот
2. Креирање на процес од некој друг процес
3. Креирање на процес по барање на корисник
4. Иницирање на (batch) пакетни задачи

6
Услови за запирање на процес
1. Нормален излез (своеволно)
2. Излез поради грешка (своеволно)
3. Фатална грешка (насилно)
4. “Убивање” од друг процес (насилно)

7
 Родителите креираат деца процеси, децата
може да креираат свoи процеси
 Во UNIX се формира хиерархија и таа се
нарекува група од процеси
 Windows нема концепт на хиерархиско
формирање. Сите процеси се еднакви

8
 Ги дефинира моменталната активност на
процесот
◦ Нов: процесот е креиран;
◦ Активен: инструкциите се извршуваат;
◦ Чека (блокиран): процесот чека да се случи
нешто (В/И или прием на сигнал);
◦ Спремен: процесот чека да му биде назначен
CPU – останатите ресурси му се доделени;
◦ Терминиран: процесот завршил;
 Транзиции:
◦ Програмски акции
(системски повици)
◦ OС акции
(распределување)
◦ Надворешни
настани (прекини,
interrupts)
 Најниското ниво ги обработува прекините и
врши распределба на извршувањето на
процесите - распоредувач
 Повисокото ниво се процеси за кои може да
се смета дека се извршуваат секвенцијално
12
 ОС одржува табела на процеси
◦ Еден влез по процес
◦ Претставува низа на структури

 За секој процес постои контролен блок на


процесот (Process Control Block - PCB) кој
◦ ги опишува неговите компоненти
◦ дозволува ефикасен и централизиран пристап до сите
информации во врска со процесот

◦ Редовите на чекање обично користат покажувач кон PCB-


ата
 Идентификационен број на процесот (PID)
◦ еднозначен
 Состојба на процесот
 Програмски бројач
◦ адреса на следната инструкција што треба да се изврши
за тој процес;
 Регистри на CPU
◦ зачувување на информацијата за состојбата при прекин,
за да може процесот да продолжи каде што застанал;
 Информација за CPU - распоредување
◦ покажувачи за редовите на чекање
◦ приоритет на процес;
 Информации за управување со меморија
◦ мемориски описи (во зависност од тоа каква меморија
користи ОС);
◦ Base и limit регистар и табелата на страници
 Кориснички идентификациони броеви
◦ uid, gid
 Статус на В/И
◦ Информацијата вклучува листа на В/И уреди доделени
на тој процес, листа на отворени датотеки...
 Информации за:
◦ Време на користење на CPU;
◦ реално време на извршување
◦ лимити и квоти на користење
 Покажувачи кон таткото, децата
Полиња во табелата за процеси
16
 Контекстот е претставен во PCB и се состои од:
◦ Вредност на CPU регистри;
◦ Статус (состојба) на процес;
◦ Информација за управување со меморија

 Процесот има свое множество “приватни” CPU


регистри
◦ во главната меморија
◦ се полнат со информација кога процесот преминува од
спремен во активен
◦ мора да се зачуваат назад во главната меморија кога
процесот преминува од “активен” во спремен или чека
В/И
 Промена на контекстот (context switch) –
доделување, промена на CPU на друг процес, се
прави кога се случува прекин, системски повик
или според режим на работа;

 Скапа операција
◦ Кернелот го снима контекстот на стариот процес во
неговиот PCB
◦ Кернелот го вчитува контекстот на новиот процес кој
треба да се извршува;
◦ Таа е битен фактор на ефикасноста на ОС и нејзината
цена продолжува да расте со забрзувањето на CPU
◦ Покомплексен ОС – повеќе работа при промена на
контекстот
 Прекин од истечено време (clock interrupt)
◦ процесот го потрошил доделеното време
 I/O прекин
 Мемориска грешка (Memory fault)
◦ мемориската адреса е во виртуелната меморија, па мора
прво да се доведе до работната
 Замка (Trap)
◦ се случила грешка
◦ може да доведе процесите да преминат во Exit состојба
 Системски повик
◦ отворање на датотека
◦ Крај на процес
 Нов процес се креира со fork()

 Изведување на програма - exec() фамилија

 Завршување – exit()
 Креира дете - процес
◦ два различни процеса извршуваат копија од еден
ист програм
 Детето - процес наследува од родителот:
◦ идентични копии на променливите и меморијата
(адресен простор)
◦ идентични копии на сите CPU регистри (освен
еден)
 Двата процеса (родителот и детето) се
извршуваат од истата точка по враќањето од
повикот fork():
◦ за детето - процес fork() враќа 0 (PID за детето)
◦ за родителот - процес, fork() го враќа
идентификациониот број на процесот – дете

 Едноставната имплементација на fork():


◦ алоцира меморија за детето - процес
◦ ја копира меморијата и CPU регистрите од родителите во
детето – процес
◦ скапо!
if (fork() == 0) {
main() …
… }
int pid = fork(); // create a child
...
if (pid == 0) { // child continues here

}
else { // parent continues here

}
Кодот на родителот и на детето се во иста
„програма“
Детето ги наследува сите отворени датотеки и
мрежни конекции
 exec: execl, execle, execlp, execv, execve, execvp,
или exect

 exec потпрограмата, во сите нејзини форми,


извршува нов програм во повикувачкиот процес.

 exec потпрограмата не создава нов процес, туку


го препокрива тековниот програм со нов (new-
process image)

 Тој овозможува процесот да зададе аргументи


(argc) и низа стрингови (argv)
 Во процесот - родител:
main()

int pid = fork(); // create a child
if (pid == 0) { // child continues here
exec(“program”, argc, argv0, argv1, …);
}
else {
// parent continues here

}

 Во 99% случаи, се користи exec() по повикот


fork()
 По завршувањето, програмата извршува системски повик
exit()
 Овој системски повик:
◦ го зема “резултатот” вратен од програмата како аргумент,
◦ ги затвора сите отворени датотеки, линкови итн.
◦ ја деалоцира меморијата
◦ ги деалоцира повеќето од структурите на ОС што го
поддржувале процесот
◦ проверува дали родител - процесот е жив:
 Процесот – дете ја чува резултантната вредност додека
таткото не ја побара, не умира туку влегува во
zombie/defunct статус
 Процесите имаат две карактеристики:
◦ Поседуваат ресурси
◦ Тек на извршување – следи тек (thread) на
извршување

 Овие две карактеристики се третираат


независно од ОС
 Извршувачки контекст
◦ Program counter (PC)
◦ Stack pointer (SP)
◦ Data registers
 Код
 Податоци
 Стек
Стек сегмент

Сегмент за чување на динамички


креирани променливи

Податочен сегмент

Сегмент за код

49
 Паралелизам во рамките на даден процес
(Multithreading)
 Паралелно извршување во ист адресен
простор
 Кооперативност меѓу нишките (не постојат
системски механизми за заштита)
addrX: A(int tmp) {
.
. if (tmp<2)
. B();
addrY: printf(tmp);
. }
.
. B() {
C();
addrU: }
.
. C() {
. A(2);  Се чуваат привремени
addrV: } резултати
.
. A(1);  Овозможува рекурзија
.
addrZ: exit;  Значајно за модерните
јазици
A: tmp=1
addrX: A(int tmp) { ret=addrZ
. Stack
. if (tmp<2) Pointer
. B();
Stack Growth
addrY: printf(tmp);
. }
.
. B() {
C();
addrU: }
.
. C() {
. A(2);
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
. Stack
. if (tmp<2) Pointer
. B();
Stack Growth
addrY: printf(tmp);
. }
.
. B() {
C();
addrU: }
.
. C() {
. A(2);
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
.
. if (tmp<2)
B: ret=addrY
. B(); Stack
Pointer
addrY: printf(tmp);
. } Stack Growth
.
. B() {
C();
addrU: }
.
. C() {
. A(2);
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
.
. if (tmp<2)
B: ret=addrY
. B();
addrY: printf(tmp); C: ret=addrU
Stack
. } Pointer
.
. B() {
Stack Growth
C();
addrU: }
.
. C() {
. A(2);
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
.
. if (tmp<2)
B: ret=addrY
. B();
addrY: printf(tmp); C: ret=addrU
. } A: tmp=2
. ret=addrV
B() { Stack
.
Pointer
C();
addrU: } Stack Growth
.
. C() {
. A(2);
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
.
. if (tmp<2)
B: ret=addrY
. B();
addrY: printf(tmp); C: ret=addrU
. } A: tmp=2
. ret=addrV
B() { Stack
.
Pointer
C();
addrU: } Stack Growth
.
. C() {
Output:
. A(2);
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
.
. if (tmp<2)
B: ret=addrY
. B();
addrY: printf(tmp); C: ret=addrU
. } A: tmp=2
. ret=addrV
B() { Stack
.
Pointer
C();
addrU: } Stack Growth
.
. C() {
Output:
. A(2); 2
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
.
. if (tmp<2)
B: ret=addrY
. B();
addrY: printf(tmp); C: ret=addrU
Stack
. } Pointer
.
. B() {
Stack Growth
C();
addrU: }
.
. C() {
Output:
. A(2); 2
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
.
. if (tmp<2)
B: ret=addrY
. B(); Stack
Pointer
addrY: printf(tmp);
. } Stack Growth
.
. B() {
C();
addrU: }
.
. C() {
Output:
. A(2); 2
addrV: }
.
. A(1);
.
addrZ: exit;
A: tmp=1
addrX: A(int tmp) { ret=addrZ
. Stack
. if (tmp<2) Pointer
. B();
Stack Growth
addrY: printf(tmp);
. }
.
. B() {
C();
addrU: }
.
. C() {
Output:
. A(2); 2
addrV: } 1
.
. A(1);
.
addrZ: exit;
addrX: A(int tmp) {
.
. if (tmp<2)
. B();
addrY: printf(tmp);
. }
.
. B() {
C();
addrU: }
.
. C() {
Output:
. A(2); 2
addrV: } 1
.
. A(1);
.
addrZ: exit;
 Извршувачки
контекст
◦ Program counter (PC)
◦ Stack pointer (SP)
◦ Data registers
 Процесите ги групираат ресурсите

 Нишките се нивни извршувачки


подентитети кои се распоредуваат за
извршување од CPU
 Можност на ОС да поддржи повеќе и
конкурентни текови на извршување додека сме
во истиот процес
 MS-DOS
поддржуваше по еден
кориснички процес
до по една нишка

 Некои стари UNIX,


поддржуваат повеќе
кориснички процеси,
но само по една
нишка по процес
 Java run-time
околината е едно
процесна, но со
повеќе нишки
 Повеќекратни процеси
и нишки се наоѓаат во
Windows, Solaris, и
многу модерни верзии
на UNIX
 Поедноставно (побрзо) се создаваат и
уништуваат отколку процесите
 Менувањето нишки е побрзо од менување
процеси
 Нишките комуницираат меѓу себе без
потреба од јадро
 Забрзување на апликациите – во ситуации
кога има многу процесорска активност, а
истовремено и значителни влезно-излезни
процеси
 Можна вистинска паралелност – кај системи
со повеќе CPU
 Нека корисникот пишува книга и нека во
даден момент е потребно да се изврши
промена на текстот
 Доколку има само еден процес (со една
нишка), тогаш потребно е во исто време да се
следат
◦ Командите од корисникот (од тастатура и глушец)
◦ Преформатирање на текстот
◦ Снимање на новата содржина на диск
 Решение со процеси: Сложен програмски
модел базиран на прекини!!!
 Подобро решение
 Да имаме процес со три нишки
1. за интеракција со корисникот
2. за преформатирање на текстот по потреба
3. за запишување на содржина на дискот
 Трите нишки ја споделуваат заедничката
меморија, па така имаат пристап до
документот што се обработува.
 Опцијата со три посебни процеси (наместо
три нишки) не функционира во овој случај!
72
 Вообичаен пристап:
◦ Прочитај блок податоци
◦ Обработи го
◦ Запиши го
 Проблем: Ако се достапни само блокирачки
системски повици, процесот се блокира
додека влегуваат и излегуваат податоци
 Залудно трошење на ресурските – CPU без
работа!
 Решение: Нишки
 Процесот може да се структурира со три
нишки:
1. за влез
2. за обработка
3. за излез
 Овој модел функционира само ако
системскиот повик ја блокира нишката што
повикува, а не целиот систем!
 Нишките го споделуваат истиот адресен
простор на процесот кој ги креирал
◦ Процесите имаат сопствен независен адресен
простор
 Нишките имаат директен пристап до
податочниот сегмент на процесот
◦ Процесите имаат своја копија на податочниот
сегмент од родителот-процес
 Нишките можат директно да комуницираат
помеѓу себе
◦ Процесите мораат да користат посложена меѓу-
процесна комуникација
 Нишките немаат многу додатни податоци
(overhead)
◦ Процесите имаат значителна количина на додатни
податоци
 Не постои посебен прекин за воведување на
мултипрограмирање кај нишките, тие
соработуваат
 Креирање на нишки е едноставно и брзо
◦ Креирање на нов процес бара дуплирање на родител-
процесот.
 Нишките можат да имаат контрола врз нишките
од истиот процес
◦ Процесите имаат контрола само врз процесите-деца.
 Промени во главната нишка (октажување,
промена на приоритет...) можат да имаат
влијание на однесувањето на другите нишки
◦ Промени кај родител-процесот не влијаат на
децата-процеси.
 Сите нишки мораат да го извршуваат истиот
извршен код
◦ Децата-процеси можат да извршат комплетно
различен код преку повик на exec().
 За време на промена на нишка, виртуелниот
мемориски простор останува ист
◦ Кај промена на котекст на процес, се менува
виртуелниот мемориски простор.
 И процесите и нишките му ја препуштаат
контролата на оперативниот систем при
промена на контекст.
◦ Процесот на предавање на контролата на јадрото па
назад на процесите, заедно со проеманата на
вредностите на регистрите се најголемата цена во
изведување на промена на контекст.
 При промена на контекст на процес, се
пребришува TLB и кеш меморијата (на
почетокот пристапот до меморијата е поскап)
◦ Кај промена на контекст на нишки ова не се случува
бидејќи нишките го споделуваат истиот адресен
простор.
Меѓупроцесна комуникација
Проф. Д-р Димитар Трајанов
Вон. проф. Д-р Невена Ацковска
Вон. проф. Д-р Боро Јакимовски
Вон. проф. Д-р Весна Димитрова
Вон. проф. Д-р Игор Мишковски
Доц. Д-р Сашо Граматиков
 Меѓупроцесна комуникација (IPC)
◦ Критична секција
◦ Натпревар на процеси
◦ Техники за решавање
 заклучувачки променливи
 хардверски решенија
 семафори
 монитори
◦ Класични проблеми на синхронизација
 Потреба од комуникација меѓу процесите
 Потреба од синхронизација при критичните
активности
 Потреба од редослед на операции
 Два процеси А и B сакаат да
Spooler
печатат
..
.  Во моментот кога процесот A ја
чита заедничката променлива in
и ја меморира во локална
4 abc out = 4 променлива sled-slob, му
поминува времето на работа
5 program x
 Доаѓа процесот B, ја чита in,
6 program y добива вредност 7, ја праќа
Proces A датотеката на таа локација и ја
поставува in на 8
7 in = 7
DocA
DocB  Процесот A се активира одново
Proces B .. и ја праќа датотеката како што
. му кажува променливата sled-
slob, на локацијата 7, “газејќи” ја
датотеката на процесот B
ПРОБЛЕМ: процесот B почнува да користи заедничка (shared)
променлива пред A да заврши со неа
 Ситуации во кои повеќе процеси читаат
или запишуваат во заеднички ресурс
(променлива, датотека) и целокупниот
резултат зависи од редоследот на
извршување на процесите
 Проблемите кои ги предизвикуваат
условите на трка тешко се детектираат
 Потребно е да се избегнат по секоја
цена
◦ Взаемно исклучување на процесите при
користење на заеднички ресурси
 Критичен сегмент е дел од програмата
каде се пристапува до заедничка
меморија (променливи), датотеки, итн.

 Претставува апстракција што се состои


од број на последователни програмски
наредби кои треба да се извршуваат без
прекин и грешки
shared double balance;

Код за p1 Код за p2
. . . . . .
balance = balance + amount; balance = balance - amount;
. . . . . .
shared double balance;
Код за p1 Код за p2
... ...
balance = balance + amount; balance = balance - amount;
... ...

Код за p1 Код за p2
load R1, balance load R1, balance
load R2, amount load R2, amount
add R1, R2 sub R1, R2
store R1, balance store R1, balance
 Постои натпревар на процеси; кој да ја
изврши својата критична секција

 Секциите можат да бидат дефинирани од


различен код во различни процеси
◦ не е лесно да се детектира со статичка анализа

 Без взаемно исклучување, резултатите од


повеќекратните извршувања може да се
неконзистентни

 Потребен е ОС механизам за корисникот да


може да се справи со натпреварите на
процеси
 Даден е систем од n процеси {P0, P1, … Pn-1}

 Секој процес има критична секција (менува


вредност на променливи, табели, запишува
датотеки кои се заеднички со други процеси...)

 Правило:
Кога еден процес работи во својата критична
секција, ниту еден друг процес нема дозвола да
извршува во својата критична секција

 Треба да се дизајнира протокол за кооперација на


процесите
 Секој процес мора да бара дозвола да влезе во
критичната секција
 Критичната секција може да е следена од
излезна секција

do {
entry_section
critical_section _
exit_section
reminder_section
}
 Оневозможи прекини

 Софтверски решенија – заклучувањe


променливи (брави, locks), семафори

 …
 Секоја имплементација мора да биде:
◦ коректна: само еден процес може да ја
извршува критичната секција во еден момент

◦ ефикасна: влегувањето и излегувањето од


критичната секција мора да биде брзо

◦ флексибилна: добрата имплементација


дозволува максимална конкурентност и има
минимален број на ограничувања
 Коректното решение мора да ги има следниве својства:
1. Взаемна исклучивост: ако еден процес работи во критична
секција, ниеден друг не смее да работи во својата критична
секција (најмногу еден)

2. Прогрес: ако нема процес што моментално работи во


критичната секција, а има процеси што сакаат да работат во
критичната секција, тогаш еден од нив добива дозвола
(најмалку еден)

3. Ограничено чекање: мора да има граница на бројот на


дозволи која ја добиваат други процеси за влез во својата
критична секција пред да биде услужен даден процес што
има барање за влез во критична секција (ниту еден процес не
смее да чека бесконечно долго за влез во својата критична
секција)
А Процесите (Р0 и Р1) делат заедничка променлива
л turn.
г  Кога turn==i, тогаш процесот Рi има дозвола да
о влезе во критичната секција. Другиот процес е Рj
р за j==1-i;
и
т
а
м

1
 Решението овозможува само еден процес да биде во едно време
во критичната секција.

 Не задоволува прогрес: потребна е стриктна алтернација на


процесите кои се одвиваат во критична секција.

 Проблем е ако едниот процес е многу поспор од другиот

Процес 0 Процес 1
turn = 0
wait for turn = 0 noncritical_region (enter)
critical_region (enter)
critical_region (finish)
turn = 1
noncritical_region (enter)
noncritical_region (finish)
wait for turn = 0 (правило 2 е прекршено)
 Алгоритам 1 не содржи доволно информации за
состојбите на секој процес, туку само на кој процес му е
дозволено да влезе во критичен сегмент

 Се воведува низата boolean flag[P1..P2]

 Ако flag[Pi] e true, i-тиот процес Pi e подготвен да влезе


во критичната секција

 i-тиот процес проверува дали j–тиот процес НЕ е спремен


да влезе во неговиот критичен сегмент

 Ако и flag[Pj] e true, тогаш Pi чека додека flag[Pj] стане


false, па тогаш Pi ќе влезе во критичниот сегмент
Flag[P1..P2]
А Process 1 Process 2
Flag[P1] = true; Flag[P2] = true;
Л
while(Flag[P2]) while(Flag[P1])
Г
; // wait ; // wait
О /* enter C.S. */
/* enter C.S. */
Р /* leave C.S. */
/* leave C.S. */
И Flag[P2] = false; g[ ]
Flag[P1] = false;
Т ………………. ………………..
А
М

2
Взаемно исклучување со работно чекање
Проблем:
deadlock: (Flag[P1]=true , Flag[P2]=true), бесконечен циклус
Правилото 3 е прекршено.
 Со комбинација на претходните два алгоритма
се добива алгоритам што ги исполнува 3те
барања за коректност

 За да влезе во критичен сегмент Pi го сетира


flag[Pi] на true, и поставува turn=Pj, со што
означува дека ако другите процеси сакаат да
влезат во критичен сегмент, можат

 Оној процес што го сетира flag-от и добие своја


вредност во променливата turn, влегува во
критичен сегмент
Flag[P1..P2], turn
Process 2
А Process 1
Л Flag[P2] = true;
Flag[P1] = true;
Г turn = P1;
turn = P2;
О while(Flag[P1] and turn == P1)
while(Flag[P2] and turn == P2)
Р ;
;
/* enter C.S. */
И /* enter C.S. */
/* leave C.S. */ / /
Т /* leave C.S. */
Flag[P2] = false;
Flag[P1] = false;
А ………………...
………………...
М

Ова е идеја на Peterson-овото решение


(модерна верзија на Dekker-овиот алгоритам
#include <prototypes.h>
#define FALSE 0
#define TRUE 1
#define N 2 // number of processes
turn int turn, interested[N] // all values initially 0
void enter_region(int process)
{
int other; // number of the other process
other = 1 - process;
interested[process] = TRUE; // show that you are interested
turn = process; // set the flag
while ( turn == process && interested[other] == true) ; // wait
}
void leave_region(int process) { // process who is leaving (0 or 1)
interested[process] = FALSE; // indicate departure from critical
region
}
 Исклучување прекини
 Специјални машински инструкции
 За системи без нишки (threads), прекините се единствен
извор на проблеми поврзани со конкурентност и
синхронизација

 Едноставно решение:
◦ Исклучи ги прекините пред почетокот на критичниот сегмент
◦ Вклучи ги прекините по критичниот сегмент
со исклучени прекини, нема временско ограничување за
процесот

 За ОС исклучувањето на хардверските прекини е опасно:


може да доведе до одложување на одговор на важни
настани

 Не е соодветно за генерална техника за кориснички


процеси
◦ Критичните сегменти мораат да бидат куси
◦ Не е соодветно кај системи со повеќе процесори (јадра)
shared double balance;

Код за p1 Код за p2
disableInterrupts(); disableInterrupts();
balance = balance + amount; balance = balance - amount;
enableInterrupts(); enableInterrupts();

 Прекините може да бидат оневозможени


произволно долго
 Ние сакаме само p1 и p2 да не се мешаат меѓу себе;
ова ги блокира сите pi
 Да искористиме заедничка брава “lock” променлива
 Специјалните машински инструкции
◦ се изведуваат во единечен инструкциски циклус
◦ не се подложни на меѓусебно мешање на
инструкциите
◦ Се регулира достап до мемориска локација
 читање и запишување
 читање и тестирање
 се изведува атомично, во еден циклус, без
прекини
 Оваа инструкција не може да биде прекината –
никој не може да пристапи до меморијата
додека таа се извршува

boolean testset (int i) {


if (i == 0) {
i = 1;
return true;
}
else {
return false;
}
}
 Заедничка boolean boolean testset (int i) {
променлива lock., if (i == 0) {
иницијализирана на false. i = 1;
 Решение: return true;
}
else {
while (true) { return false;
while ( !TestAndSet (&lock )) }
; /* do nothing }

// critical section

lock = FALSE;

// remainder section

}
 Exchange инструкција
 замена меѓу регистар и мемориска локација
 атомична операција, во една инструкција
void exchange(int register, int memory) {
int temp;
temp = memory;
memory = register;
register = temp;
}
 Предности
◦ можат да се искористат за било кој број
процесори кои може да делат работна
меморија

◦ едноставни се за работа и за верификација

◦ можат да се искористат за неколку критични


секции
 Неповолности
◦ зафатеното чекање троши процесорско време
◦ можно е изгладнување кога некој процес
излегува од критична секција, а повеќе од еден
процес чекаат на неа
 Овие пристапи (работно чекање) непотребно го
трошат процесирачкото време чекајќи да добијат
дозвола за влез во критичниот сегмент
 Пример. 2 процеса,
◦ H – со висок приоритет (веднаш му се доделува CPU кога
е во спремна состојба)
◦ L – со низок приоритет
◦ Кога L e во критичен сегмент, H станува спремен и му се
доделува CPU . Тогаш H почнува со работно чекање, но L
не може да излезе од критичниот сегмент бидејќи H
работи (иако чека).
Со тоа H е во бесконечен циклус
 Подобро е да се користат некои системски
повици кои го блокираат процесот на кој му е
дозволен влез во критичниот сегмент

 На пример:
◦ sleep() да го суспендира процесот додека некој друг не
го разбуди со wakeup()
◦ wakeup() има еден параметар, процесот кој треба да се
разбуди

 Системските повици од овој тип водат кон


решенија со блокирање
 Важен поради: мрежни интерфејси, В/И контролери,
размена на пораки итн.

 Кружен бафер со ограничен капацитет


 Пристап: Додавање на крајот, земање од почетокот
 Модел на произведувач/потрошувач со: N : број на места,
count : број на пополнети
#include <prototypes.h>
#define N 100 // number of slots
int count 0;
void consumer (void) {
void producer (void) {
int item;
int item; while (TRUE) {
while (TRUE) {
if (count == 0) sleep(); // empty?
produce_item(&item); // next item
remove_item(&item); // take item
if (count ==N) sleep(); // full? count = count - 1;
enter_item(item); // put item
if (count == N-1)
count = count + 1;
wakeup(producer); // full?
if (count == 1) consume_item(item); // print item
wakeup(consumer); // empty? }}
}}

Во ова решение променливата count не е заштитена!


Producer Consumer

count=0, read_count

insert_item()
count++
wakeup(consumer) Problem: consumer is
not sleeping (signal is
lost)
wait for next item

count=0 => sleep

insert_item()

count =N => sleep Both processes sleep
forever! 39
 Решенијата со работно чекање тешко се генерализираат за
покомплексни проблеми

 Се користат семафори

 Семафорот се состои од:


◦ Променлива value
◦ Листа на процеси L
◦ Кон семафорот се пристапува со
 Функција wait (down, sleep) – блокира процес
 Функција signal (up, wakeup) – буди процес

 Пример: Semaphore s(5);


 Процесот ја повикува wait во критичен момент и
во зависност од вредноста на променливата
value во семафорот, добива дозвола за
продолжување или станува блокиран.

 Процесот ја повикува signal по поминување на


критичниот сегмент и така ослободува еден
процес да помине низ семафорот.
◦ Ослободениот процес поминува во спремна состојба и се
сместува во редицата со спремни процеси (CPU се
доделува според алгоритам за распределување)
 Променливата value одредува колку
процеси можат симултано да работат
(пропусна моќ на семафорот, т.е. колку
процеси може истовремено да се
опслужат – пример 3 печатачи).

 Овие кодови се извршуваат атомично, т.е


додека се одвива операцијата со
семафорот, ниту еден друг процес нема
пристап до семафорот
typedef struct{
int value;
struct process *L;
} semaphore;
void signal (semaphore S) {//wakeup,
up
void wait(semaphore S) { // sleep, down S.value++;
S.value --; if (S.value ≤ 0) {
if (S.value < 0) { Remove a process P from S.L;
add process to S.L; wakeup(P);
block(); }
} }
}
 Бројачки семафори – целобројни
вредности - неограничени
 Бинарни семафори – целобројни
вредности меѓу 0 и 1; полесни за
имплементација
◦ попознати како mutex брави

 Бројачкиот семафор S може да се


имплементира како бинарен
 n процеси делат ист семафор mutex.
 Секој Pi е организиран:
do {
wait(mutex);
critical_section
signal(mutex);
non critical section
} while(1)
 Два процеса кои работат конкурентно:
◦ Р1 има наредби Ѕ1, а Р2 има Ѕ2
 Нека наредбите Ѕ2 треба да се извршат откако
завршиле наредбите Ѕ1, без разлика кој процес
го добил прв CPU
 Р1 и Р2 користат заеднички семафор sync=0 во
својот код:

S1; wait(sync);
signal(sync); //vo P1 S2; //vo P2

 Бидејќи sync==0, Р2 ќе ги изврши Ѕ2 само откако


Р1 ќе повика signal(sync); што е по Ѕ1
 Доаѓаат како дел од програмски јазик, односно
мора да имаат поддршка од компајлерот

 Претпоставка дека процесите се состојат од


локални податоци и код што оперира над тие
податоци
 Локалните податоци може да се достапат само
преку програмата што е енкапсулирана во
самиот процес ...т.е. еден процес не може
директно да достапи кон локални податоци на
друг
 Процесите може да делат глобални податоци
 Множество на процедури, променливи и
податочни структури групирани во специјален
вид модули

 Процесите можат да го повикаат мониторот во


секој момент, но не можат директно да
пристапат до внатрешните податочни структури
на мониторот со процедури декларирани надвор
од мониторот
 Монитор е Monitor M {
конструкција многу int a, b, c ;
слична на денешните condition x, y, z ;
објекти во fn1(…);
програмските јазици fn2(…);
како C++, Java ... …
 Се состои од: fnm(…);
◦ Општи променливи (a, b, { init code}
c) }
◦ Методи (fn1(…), fn2(…);
fnm(…);)
◦ Иницијален код
(конструктор)
◦ Условни променливи
(x,y,z)
 Само еден метод (процес) во мониторот може да
биде активен во еден момент - взаемно
исклучување)

 Програмерот не треба експлицитно да


програмира ограничувања заради
синхронизација (тоа го врши компајлерот)

 Со додавање на сите критични сегменти како


процедури (функции) на мониторот, нема да има
конкурентно извршување на процесите во
критичните сегменти
 Со додавање на условни променливи, се
збогатува управувањето со процесите

 Условните променливи имаат две операции:


◦ x.wait - процесот кој ја повикува оваа
операција блокира (чека во ред), се додека
некој друг метод (процес) не ја сигнализира
променливата со ...
◦ x.signal - деблокира некого што чека на
променливата (... но, со тоа би имале 2 активни
процеси во мониторот...)
 Процесот кој ја продуцирал операцијата
signal, го напушта мониторот (се
блокира), а се активира процес кој чека на
условната променлива x.

 Ако условната променлива е


сигнализирана, а никој не чека на неа,
сигналот се губи
◦ Wait мора да постои пред signal
fn1(…)

x.wait // P1 blocks fn4(…)

x.signal // P2 blocks

// P1 resumes
// P1 finishes // P2 resumes
1. Проблем на произведувач/потрошувач
(producer/consumer) (проблем на
ограничен бафер дефиниран претходно)

2. Филозофи што вечераат

3. Проблем на читач/пишувач (reader/writer)


Филозофите
размислуваат:
- ги оставаат стапчињата
десно и лево
јадат:
- ги земаат стапчињата лево
па десно
- се зема едно стапче во еден
момент
- ако стапчето не е на маса,
мора да се чека соседот што
јаде да заврши и почне да
размислува

Важно: Го моделира натпреварот за ресурси меѓу процесите


Клучно барање: Филозофите не смеат да прегладнат !!!
 Гарантира дека 2 соседа нема да
јадат симултано
 Без наредбите Down(&mutex); и
Up( &mutex); што би се случило ако:
Philosopher 0 го земе стапчето 0
Philosopher 1 го земе стапчето 1
Philosopher 2 го земе стапчето 2
Philosopher 3 го земе стапчето 3
Philosopher 4 го земе стапчето 4
Ниту мислат, ниту јадат!
Подобрувања:
Кога ќе го земеш левото стапче, ако
десното е зафатено, врати го левото и
чекај случајно време

 Решението е коректно, но неефикасно


бидејќи само еден филозоф ќе јаде во
еден момент (иако можат двајца кога
има 5 стапчиња)
Решение (дел 1) 62
Решение (дел 2) 63
 Пристап до податоци при мултипрограмирање
(датотека или запис):
 Еден или повеќе процеси може да читаат слог од
датотека истовремено
 Само еден може да запишува

 Важно за:
◦ трансакции (пример продавање билети, банки, итн.)
◦ Датотечни системи
 Деливо: за читање
 Ексклузивно: за пишување

 Правила:
◦ Кога се прави ексклузивно заклучување, ниеден друг процес не
смее да има пристап
◦ Кога се прави деливо заклучување, други можат да читаат, но
никој не може да добие ексклузивно заклучување (да запишува)

 Тип на работа
◦ Се преферира читање
 Ако дојде нов процес за читање тој влегува ако нема тековно
запишување, т.е. влегува иако други веќе чекаат за запишување
◦ Се преферира запишување
 Ако дојде нов процес за запишување, тој се опслужува колку што е
можно побргу
 Пристигнуваат: r1 r2 r3 w4 r5 w6 r7
се преферира читање се преферира запишување
mutex – контролира промена на променливата rc
db – контролира влез во база податоци
rc – број на процеси за читање
 Се користи за моделирање
на ситуации со редови на
чекање каде треба да се
донесе одлука дали
корисникот да чека и да му
се соопшти дека редот е
полн и да се обиде
повторно после некое
време

68
 Може да настане проблем бидејќи не се знае
времетраењето на акциите на берберот и
муштеријата.
◦ Муштеријата доаѓа и гледа дека берберот шиша, па затоа
оди во чекалната.
◦ Додека оди накај чекалната, берберот завршува со шишање,
па затоа оди кон чекалната за да провери дали има
муштерии
◦ Бидејќи нема никој во чекалната (муштеријата сеуште не
стигнал во чекалната), берберот оди кон својата столица и
заспива на неа
◦ Сега берберот чека да дојде муштерија, а муштеријата чека
да стане берберот

69
70
Распоредување на процеси
Проф. Д-р Димитар Трајанов
Вон. проф. Д-р Невена Ацковска
Вон. проф. Д-р Боро Јакимовски
Вон. проф. Д-р Весна Димитрова
Доц. Д-р Игор Мишковски
Доц. Д-р Сашо Граматиков
 Распоредување на процеси
 Мерки за перформанси
 Разлики во начините за распоредување
◦ Пакетни системи
◦ Интерактивни системи
◦ Системи кои работат во реално време
 Кога повеќе од еден процес се во ready
состојба треба да се одлучи кој од нив ќе
го добие CPU
 Делот од оперативниот систем кој ги прави
овие одлуки се нарекува распоредувач
(scheduler)
 Распоредувачот работи врз основа на некој
алгоритам за распоредување

3
 извршувањето се состои
од циклуси на CPU
извршување и I/O чекање
а) CPU доминантен процес
б) I/O доминантен процес

5
1. Кога процес од извршување доаѓа во
состојба на чекање (I/0 барање или
повикување wait до завршување на процес
дете)
2. Процес оди од состојба на извршување во
состојба спремен (се случил прекин)
3. Процес се менува од состојба на чекање
во спремна состојба (завршил I/0)
4. Кога терминира процесот
 Ресурсите можат да бидат поделени во една од двете групи
 Типот на ресурси одредува како ОС го управува
1) Non-preemptible ресурси (кои не се одземаат)
◦ Откако е доделен ресурсот, не може да се користи се’ додека
не биде ослободен
◦ Потребни се повеќе инстанци од ресурсот
◦ Пример: Блок на диск
◦ ОС менаџмент: алокација
 Одлучува кој процес го добива кој ресурс
2) Preemptible ресурси (кои се одземаат)
◦ Може да е одземен ресурсот, потоа се враќа
◦ Може да има само еден од овој тип ресурс
◦ Пример: CPU
◦ ОС менаџмент: распоредување
 Одлучува по кој редослед се опслужуваат барањата
 Одлучува колку долго процесот го држи ресурсот
 Во дадени периодични временски
моменти (прекини од системскиот
часовник)

◦ Non-preemptive: процесот се извршува


додека тој самиот не блокира или
заврши

◦ Preemptive: процесот може да го


користи CPU во рамките на некој
предефиниран максимален временски
период

8
 Проток (throughput) –број на процеси завршени
во единица време
 Време до завршување, време во систем
(turnaround time) – времето поминато од
доставувањето до комплетирањето на процесот
 CPU искористеност - процент од времето во кое
процесорот е зафатен
 Време на чекање – време на чекање (за CPU)
поминато во редицата на спремни процеси
 Време на одзив – во интерактивни системи
времето на завршување не е добра мерка. Време
од поднесување барање до прв добиен резултат
 Во зависност од типот на системот постојат
различни алгоритми
◦ Пакетни (Batch)
 Пресметка на камати, процесирање на случаи кај
осигурителна компанија
 Нема корисници
 Non preemptive или preemptive со долги временски
периоди
◦ Интерактивни
 Preemptive
◦ Во реално време (Real-Time)
 треба да бидат исполнети роковите
 Понекогаш нема потреба од preemptive

11
 За сите системи
◦ Фер – секој процес да добие соодветно време на
CPU
◦ Спроведување на политиката за распоредување
◦ Баланс – сите делови на системот да работат

 За пакетни системи
◦ Максимизирај проток
◦ Минимизирај време на завршување (од влегување
во системот до терминирање)
◦ CPU искористеност – CPU да работи цело време
 Интерактивни системи
◦ Време на одзив – одговори на барања брзо
◦ Пропорционалност – потребно е да се исполнети
корисничките барања

 Системи за работа во реално време


◦ Почитувај рокови – без губење податоци
◦ Предвидливост – избегни губење квалитет во
мултимедијални системи

13
Delay & User Reaction

0 - 16ms People are exceptionally good at tracking motion, and they


dislike it when animations aren't smooth. Users perceive
animations as smooth so long as 60 new frames are rendered
every second. That's 16ms per frame, including the time it takes
for the browser to paint the new frame to the screen, leaving an
app about 10ms to produce a frame.
0 - 100ms Respond to a user action within this time window and users feel
like the result is immediate. Any longer, and the connection
between action and reaction is broken.
100 - 300ms Users experience a slight perceptible delay.
300 - 1000 ms Within this window, things feel part of a natural and continuous
progression of tasks. For most users on the web, loading pages
or changing views represents a task.
1000+ms Beyond 1 second, the user loses focus on the task they are
performing.
10,000+ms The user is frustrated and is likely to abandon the task; they may
or may not come back later.
 Прв – Дошол Прв – Услужен
(First-Come First-Served)
 Најкратката задача прва
(Shortest Job First)
 Најкраткото преостанато време следно
(Shortest Remaining Time Next)

15
 Наједноставен алгоритам
 Лесно се програмира. Се користи поврзана листа
 Проблеми:
◦ Ако има CPU-bound процес со 1 I/O пристап во секунда,
и многу I/O-bound процеси кои треба да завршат по
1000 I/O операции, а им треба сосема малку CPU.
◦ I/O-bound процесите ќе завршат за 1000 сек затоа што
треба да чека 1000 прекини на секоја секунда кога би се
прекинал CPU-bound процесот поради негово читање од
диск.
◦ Ако насилно се прекинува CPU-bound процесот секои
10ms тогаш I/O-bound процесите ќе завршат за 10 сек.

16
 Секој процес кој што ќе премине во состојба на
спремен процес се придружува на крајот на
редицата на спремни процеси за извршување.
 Прв започнува да се извршува оној процес кој
што прв влегол во оваа редица на спремни
процеси, втор започнува процесот кој влегол во
редицата по него, итн.
 Средното време на чекање со овој алгоритам е
често доста долго.

17
 Со овој алгоритам CPU се доделува на оној
процес кој што има најмало очекувано време на
извршување.
 Овој алгоритам им дава предност на извршување
на малите процеси.
 Доколку процесите се со иста должина, тогаш се
користи FCFS за да се разреши дилемата.

18
 Потреба од познавање на времето на
извршување на зададените работи
 Пример за извршување

 Средно време во системот


◦ а) (А-8, B -12, C-16, D-20) 14 мин.
◦ б) 11 мин.
 Алгоритамот дава најдобри времиња на
завршување ако на почетокот се познати сите
задачи кои треба да се завршат
19
 Preemptive верзија на SJF
 Треба да се познава времето на
извршување
 Се пресметува преостанатото време за
извршување

20
 Се избира процесот чие што преостанато
време за извршување е помало.
 Кога ќе пристигне нов процес во редицата на
спремни процеси, неговото вкупно време се
споредува со преостанатото време на
извршување на процесот кој веќе е во состојба
на извршување.
 Ако на новиот процес му е потребно помало
време за да заврши отколку на тековниот
процес, тогаш тековниот процес се прекинува
и новиот процес преминува во состојба на
активен.

21
 Round-Robin
 Priority Scheduling
 Multiple Queues
 Shortest Process Next
 Guaranteed Scheduling
 Lottery Scheduling
 Fair-Share Scheduling

23
 За секој процес се одделува мала количина CPU
време (временски квантум)
◦ Откако ќе истече времето процесот се вади од редица на спремни
(preempted) и се додава на крајот на редицата на спремни
 Ако има n процеси во редица на спремни и
квантумот е q, тогаш секој процес добива 1/n од
CPU времето во порции од најмногу q временски
единици наеднаш. Ниту еден процес не чека повеќе
од (n-1)q временски единици.
 Перформанси
◦ q големо  FIFO
◦ q мало  q мора да е доволно големо во однос на времето
за промена на контекст
а) Листа на процеси спремни за извршување
б) Листа на процеси спремни за извршување откако
процесот B го искористил своето процесорско време
(quantum)

25
 Дефинирање на различни приоритети на
процесите според нивната важност
 На секој процес му се придружува цел број кој го
означува неговиот приоритет
 CPU се доделува на процесот со најголем
приоритет (најмал број  највисок приоритет)
◦ SJF е распоредување со приоритети каде приоритетот е
одлучен според предвиденото следно време на
извршување
 Проблем  Изгладнување – процеси со помал
приоритет може никојпат да не се извршат
 Решение  како поминува времето му се
зголемува приоритетот на процесот
 Намалување на бројот на промени на процеси
 Се дефинираат приоритетни класи и секоја
задача добива различно време за извршување
Приоритет Периоди на извршување
највисок 1
највисок-1 2
највисок-2 4
највисок-3 8

30
 Процесот може да има променлив приоритет
 Распоредувачот на повеќекратни редови со
повратна информација работи според
следните параметри:
◦ број на редови
◦ распоредувачки алгоритам за секој ред
◦ метод кој кажува кога еден процес добива повисок
приоритет
◦ метод кој кажува кога му се намалува приоритетот
на процес
◦ метод кој одлучува во кој ред се сместува процесот
кога му треба опслужување
 3 редови:
◦ Q0 – RR со квантум 8 ms
◦ Q1 – RR со квантум 16 ms
◦ Q2 – FCFS
 Распоредување
◦ Нов процес влегува во редот Q0. Кога ќе добие
CPU, задачата добива 8 ms. Ако не заврши за 8
ms, се преместува во Q1.
◦ Во Q1 задачата се распоредува и добива
дополнителни 16 ms. Ако не се заврши, се
преместува во Q2.
 Верзија на SJF за интерактивни системи
 Проблем: кој од процесите кои тековно
работат е најкус?!?

◦ Секоја команда се разгледува како посебна


работа и се мери нејзиното време на извршување

◦ Врз основа на проценка прво се извршува


најкратката команда

34
 Следното време на опслужување со CPU на еден процес
може да се предвиди според времето на опслужување на
истиот процес во минатото

 Нека
Tn е должина на n-то опслужување на тој процес
(најсвежа информација, скорешна историја - recent
history),

Fn+1 е нашата предвидена вредност за следната должина


на процесот (Fn е историја од минатото –past history)

Дефинираме рекурентна врска:


Fn+1= α ·Tn + (1- α) ·Fn,
( α го контролира влијанието на скората историја од
минатото)
 Проценка на времетраење на следно извршување на
процес :
 Нека имаме две претходни вредности за времето на
извршување на еден процес, T0 и T1
F1=T0, F2= α ·T1 + (1- α) ·F1,
FK = α ·TK-1 + (1- α) ·FK-1, K=3, 4, ...
за α = 1/2 (скората и историјата од минатото нека имаат
еднаква тежина)
T0, T0 /2 + T1/2, T0 /4 + T1/4 + T2/2, T0 /8 + T1/8 + T2 /4 +
T3/2, ...
(историјата се помалку влијае на иднината)
 - SJF е единствен оптимален (според времето на чекање)
кога сите процеси доаѓаат во ист момент, во спротивно не
е
 Потреба од гарантирање дека секој
корисник ќе добие одредено процесорско
време
 Се мери потрошеното време од секој
корисник
 Се одредуваат приоритети за процесите
врз основа на соодносот на реално
потрошеното време и предефинираното
време

37
 За едноставна реализација на распоредување во
кое ќе се доделат некои предефинирани
проценти на процесорско време се користи
распоредување со Лотарија
 Секој процес/корисник добива одреден број на
тикети кои му овозможуваат користење на даден
ресурс
 Кога ќе дојде време за распоредување на нов
процес да го користи ресурсот се генерира
случаен број во опсегот од 1 до бројот на
тикети. Процесот кој го има бараниот број на
тикет го добива ресурсот
 Процесите имаат по повеќе тикети. Бројот на
тикети е право пропорционален со веројатноста
дека тие ќе бидат избрано, односно ќе го
добијат ресурсот
38
 Се користи за решавање на проблемот кога
даден корисник за да добие повеќе процесорско
време може да стартува повеќе процеси
 Идејата е да се извршува по еден процес од
секој корисник
 Ако еден корисник има 4 процеси А,Б,В,Г а друг
има еден процес Д тогаш процесите ќе се
извршуваат по следниов редослед
◦ АДБДВДГДАД...
 Ако првиот корисник треба да добие двапати
повеќе време тогаш извршувањето би било
◦ АБДВГДАБДВГД...

39
 Главна цел е работата да се заврши во
дадениот рок
 Мора да се пресмета дали перформансите
на компјутерскиот систем задоволуваат
◦ Ако има m периодични настани
◦ Настанот i се случува со периода Pi и за да се
опслужи бара Ci секунди
 Тогаш оптоварувањето може да е поднесе
ако
m
Ci

i 1 Pi
1

40
 Нека се дадени 5 процеси: A, B, C, D и E и
соодветно нивните времиња на
извршување: 25, 22, 33, 35 и 28. Процесите
пристигнуваат (скоро) истовремено.
 Да се нацрта соодветниот Гантограм
(временски дијаграм) за секој од
распределувачките алгоритми дадени во
табелата и да се пополнат соодветните
полиња во неа.
Алгоритми за распределување

Round Robin
FCFS SJF
време на пристигнување
со квантум 10 ms
време на извршување
процес

вкупно вкупно вкупно


време на време на време на
време во време во време во
чекање чекање чекање
систем систем систем

A 25 0

B 22 0

C 33 0

D 35 0

E 28 0
 Гантограм за FCFS е:

 Вкупното време на чекање на процесите е:


Процес Време на чекање
A 0
B 25
C 47
D 80
E 115 Просечно време на чекање: 53.4 ms
 Вкупното време во системот на секој од
процесите е времето кое поминало од
нивното пристигнување, па сѐ до нивното
комплетно завршување.
Процес Време во системот
A 25
B 47
C 80
D 115
E 143
Просечно време на задржување во системот: 82 ms
 Гантограм за SJF е:

 Вкупното време на чекање на процесите е:


Процес Време на чекање
A 22
B 0
C 75
D 108
E 47 Просечно време на чекање: 50.4 ms
 Вкупното време во системот на секој од
процесите е времето кое поминало од
нивното пристигнување, па сѐ до нивното
комплетно завршување.
Процес Време во системот
A 47
B 22
C 108
D 143
E 75
Просечно време на задржување во системот: 79 ms
 Гантограм за RR со квантум 10 ms е:

 Вкупното време на чекање на процесите е:


Процес Време на чекање
A 0+(50-10)+(100-60) = 80
B 10+(60-20)+(105-70) = 85
C 20+(70-30)+(107-80)+(135-117) = 105
D 30+(80-40)+(117-90)+(138-127) = 108
Просечно време на
E 40+(90-50)+(127-100) = 107 чекање: 97 ms
 Вкупното време во системот на секој од
процесите е времето кое поминало од
нивното пристигнување, па сѐ до нивното
комплетно завршување.
Процес Време во системот
A 105
B 107
C 138
D 143
E 135
Просечно време на задржување во системот: 125.6 ms
 После пресметките табелата би изгледала
вака: Алгоритми за распределување

Round Robin со
FCFS SJF

време на пристигнување
квантум 10 ms
време на извршување
процес

вкупно вкупно вкупно


време на време на време на
време во време во време во
чекање чекање чекање
систем систем систем

A 25 0 0 25 22 47 80 105

B 22 0 25 47 0 22 85 107

C 33 0 47 80 75 108 105 138

D 35 0 80 115 108 143 108 143

E 28 0 115 143 47 75 107 135

Просек 53.4 82 50.4 79 97 125.6


 Со помош на алгоритамот SRTN да се
распределат 6 процеси A, B, C, D, E и F кои
што имаат соодветно 22, 30, 15, 28, 12 и
25 времиња на извршување. Меѓутоа,
процесите не се придружуваат истовремено
на редицата на спремни процеси. Нивните
времиња на придружување се: 5, 10, 80, 0,
15 и 50 ms соодветно.
 Да се нацрта соодветниот Гантограм и да
се пресмета времето на одзив на секој од
процесите во системот.
 Гантограм за SRTN е:

 Времето на одзив се пресметува како


резултат од времето на поднесување
барање, до прв добиен резултат.
◦ Притоа, ќе претпоставиме дека процесот веднаш
штом ќе стане активен го дава својот прв
резултат.
 Времето на одзив за процесот A би било:
◦ време на поднесување барање – 5ms
◦ прв добиен резултат – 5ms
◦ време на одзив: 5 – 5 = 0ms
 Времето на одзив за процесот B би било:
◦ време на поднесување барање – 10ms
◦ прв добиен резултат – 102ms
◦ време на одзив: 102 – 10 = 92ms
 Времето на одзив за процесот C би било:
◦ време на поднесување барање – 80ms
◦ прв добиен резултат – 87ms
◦ време на одзив: 87 – 80 = 7ms
 Времето на одзив за процесот D би било:
◦ време на поднесување барање – 0ms
◦ прв добиен резултат – 0ms
◦ време на одзив: 0 – 0 = 0ms
 Времето на одзив за процесот E би било:
◦ време на поднесување барање – 15ms
◦ прв добиен резултат – 27ms
◦ време на одзив: 27 – 15 = 12ms
 Времето на одзив за процесот F би било:
◦ време на поднесување барање – 50ms
◦ прв добиен резултат – 62ms
◦ време на одзив: 62 – 50 = 12ms
 Систем во реално време е систем каде што
времето ја игра најзначајна улога.
 Примери за таков вид системи се:
◦ Системот во компакт диск плеерите, кој што ги
зема битовите онака како што пристигнуваат од
диск единицата и ги претвора во музика во многу
краток временски интервал.
 Ако пресметката би зела подолго време, музиката
би звучела чудно.
◦ Системите во авионите, системите кои ги
контролираат роботите во една автоматизирана
фабрика, мониторирањето на пациентите во
одделите за интензивна нега, итн.
 Настаните кои се случуваат во овие системи
може да бидат периодични (се случуваат во
регуларни интервали) или непериодични
(се случуваат непредвидливо).
 Дали еден систем во реално време може да
одговори на повеќепериодичен поток од
настани (процеси), зависи од две работи:
◦ колку време му треба на секој од процесите за да
се изврши;
◦ која е неговата периода на појавување;
 Ако имаме m периодични процеси и секој
процес се појавува со периода Pi и побарува
Ci секунди од времето на CPU, тогаш
системот ќе може да управува со тој поток
само ако е задоволено следново:

 Системите во реално време кои што го


задоволуваат овој критериум се наречени
распределиви системи.
 Нека е даден еден систем во реално време
со три периодични настани. Процесите кои
што ги отсликуваат овие настани се со
периоди од 100, 200 и 500 msec,
соодветно. Ако овие процеси побаруваат
50, 30 и 100 msec од времето на CPU, дали
системот ќе може да управува со овие
процеси, односно дали системот ќе биде
распределив?
 Ако се додаде 4-ти процес со периода од
1 sec, колкаво треба да биде неговото
максимално време на извршување за да
може системот да биде распределив?
 Системот за да биде распределив треба да
го задоволува следново неравенство:

 каде што C1 = 50, C2 = 30, C3 = 100 и P1 =


100, P2= 200, P3= 500, па имаме:

 Значи овој систем може да управува со


потокот од дадените повеќе периодични
настани.
 Ако се додаде уште еден процес со
периода од 1sec = 1000 msec тогаш за
системот да биде распределив треба да
биде исполнето следново:

 Од каде што следува дека или


процесот да има максимално време на
извршување од 150 msec.
 За предвидување на времетраење на
процеси се користи алгоритам на стареење
со α=1/2. Ако времетраењата на
претходните 4 извршувања биле 40, 20, 40
и 15 ms, кое е предвидувањето за следното
време на извршување?
 Алгоритамот на стареење го пресметува
следното предвидување како тежинска
сума од претходните две извршувања, т.е.
ако Т0 и Т1 се две последователни времиња
на извршување, тогаш Т2 се пресметува
како:

T2= α·T1 + (1- α)·T0


 Проценката за времетраењето на следното
извршување на процес можеме да ја
направиме на следниов начин:
 Нека ги имаме двете претходни вредности
за времето на извршување на процесот, T0
и T1

F1=T0,
F2= α·T1 + (1- α)· F1,
Fk = α·Tk-1 + (1- α)· Fk-1, k=3, 4, ...
 Ако α=1/2 се добиваат следните
последователни предвидувања:
T0
T0/2 + T1/2,
T0/4 + T1/4 + T2/2,
T0/8 + T1/8 + T2/4 + T3/2,

 За вредностите во задачата ќе имаме


предвидување:
T0/8 + T1/8 + T2/4 + T3/2=
40/8+20/8+40/4+15/2=25ms
Блокада
Проф. Д-р Димитар Трајанов
Вон. проф. Д-р Невена Ацковска
Вон. проф. Д-р Боро Јакимовски
Вон. проф. Д-р Весна Димитрова
Доц. Д-р Игор Мишковски
Доц. Д-р Сашо Граматиков
 Ресурси – модел на систем
 Појава на блокада
 Детекција
 Справување
◦ Превенција
◦ Одбегнување
◦ Дозволи и реагирај
◦ Не прави ништо
 Системот се состои од конечен број ресурси
дистрибуирани меѓу процеси кои се натпреваруваат.
 Ресурсите се делат на неколку типови, од кои секој
има одреден број на идентични инстанци
◦ Меморискиот простор, CPU циклусите, датотеките и I/0
уредите (како принтери) се пример за типови ресурси.
◦ Ако системот има 2 CPU, тогаш ресурсот од тип CPU има две
инстанци. Слично, ресурсот од тип принтер може да има 5
инстанци
 Ако процесот бара инстанца од ресурсот, тогаш
било која инстанца од ресурсот ќе го задоволи
барањето.
◦ Во спротивно, не се работи за ист ресурс
 Ситуација кога 2 или повеќе процеси се чекаат меѓусебно
неограничено

 Множество процеси се блокирани кога некој од нив чека за


настан што може да биде предизвикан само од некој друг
процес од множеството процеси

 Се случува често кога се користат взаемни исклучувања


(работа со критични секции),

◦ Пример:
◦ Процесот A го има печатачот, а бара датотека или нејзин слог
◦ Процесот B ја има датотеката или слогот, а го бара печатачот
Proces B
Proces A
lock(r1);
lock(r2);


lock(r2); / се обидува
lock(r1); / се обидува
Бидејќи:
 Таа го спречува процесот да „напредува“
 Блокадата бара интервенција за да биде прекината
 Таа ја намалува искористеноста на ресурсите
 Сите процеси чекаат
◦ Ниту еден нема да направи настан кој би разбудил некој друг
процес
◦ Обично се чека на ослободување на ресурс, зафатен од друг
блокиран процес

 Ниту еден од процесите НЕ


◦ работи
◦ ослободува ресурс
◦ може да биде разбуден

 Сите процеси бесконечно чекаат


 Множество темиња V и множество лаци E

 V е партиционирано во два вида:


◦ P = {P1, P2, …, Pn}, множество што ги содржи сите
процеси во системот

◦ R = {R1, R2, …, Rm}, множество што ги содржи сите


ресурси во системот

 лак на барања – насочен лак Pi → Rj

 лак на доделување – насочен лак Rj → Pi


 Процес

 Ресурс од 4 инстанци

 Pi бара една инстанца на Rj Pi


Rj

 Pi држи инстанца на Rj
Pi
Rj
 ако графот нема циклуси ⇒ нема блокада

 ако графот има циклус ⇒


◦ ако има само по една инстанца од ресурсот,
тогаш има блокада
◦ ако има повеќе инстанци од ресурсот, има
можност за блокада
 Взаемно исклучување: само еден процес во еден момент
може да го користи ресурсот

 Држи и чекај: процес кој држи барем еден ресурс чека да


добие дополнителни ресурси кои ги држат други процеси

 Нема испразнување: ресурсот може да биде ослободен


само ако процесот го дозволи тоа, по комплетирање на
неговата задача

 Кружно чекање: постои множество {P0, P1, …, Pn} чекачки


процеси такви што P0 чека за ресурс кој го држи P1, P1 чека
за ресурс кој го држи P2, …, Pn–1 чека за ресурс кој го држи
Pn, и Pn чека за ресурс кој го држи P0.
 Во општ случај, постојат 4 стратегии за
решавање на блокадите:

◦ Превенција, реализирај ги ситуациите на конкурентност


во ОС така што блокада да не може да се случи

◦ Одбегнување, предвиди блокада и одбегни ја

◦ Дозволи блокада (согледај ја) и реагирај

◦ Не прави ништо (најчесто се користи во реалноста)


Услов на взаемно исклучување (1)

 Ако се избегне ексклузивно доделување ресурс


на нeкој процес - НЕМА блокада...

 Не е задолжително за деливите ресурси, но


исклучување мора да има кај што ресурсите не
можат да се делат

 Користено во јадрата на ОС
 Мора да се гарантира дека кога
процесите бараат ресурс, тие веќе не
држат друг ресурс.
◦ Мора процесите да бараат и да им се доделат
сите ресурси пред да започне извршувањето,
◦ или да му се доделат ресурси на процесот кога
истиот не држи ниту еден ресурс.

◦ Слаба искористеност на ресурсите, можно е


изгладнување
 Ако процесот кој држи некој ресурс побара друг
што не може да му биде доделен веднаш, тогаш
ги ослободува сите ресурси кои во моментот ги
држел

 Одземените ресурси му се додаваат на листа


ресурси за кои процесот чека

 Процесот ќе биде рестартиран само кога ќе може


да ги добие повторно своите стари ресурси, како
и новите кои му требаат
 Ова е најлош услов за превенција на блокади:
 Ако на процес му е доделен на пр. принтер и се наоѓа
среде работа, насилно одземање на принтерот затоа што
моментално не е слободен и потребниот плотер е лошо,
па и невозможно!
 Правило: наметни линеарно подредување на ресурсите

 Присили ги процесите да ги бараат ресурсите во дадениот


редослед
◦ процес што држи некој ресурс, не може да побара ресурс со
понизок реден број, се додека не го ослободи својот ресурс

 Постои сценарио во кое сите процеси завршуваат


блокадата никогаш нема да се случи
 Но:
◦ Нефлексибилно
◦ Не може да се прилагоди за големи програми/системи
 Кај најголемиот број системи ресурсите се
побаруваат еден по еден

 ОС треба да одлучи дали е сигурно да се додели


некој ресурс

 Прашање: Дали постои алгоритам со кој секогаш


може да се избегнуваат блокади?

 ДА...
... Но зa да се реализира, потребно е да се знаат
некои работи однапред (кои и колку ресурси се
потребни по процес!)
 Потребно е системот да има некое
претходно знаење
◦ Наједноставен и најкорисен модел е секој
процес да декларира максимален број на
ресурси од секој тип што може да ги побара.

◦ Алгоритмот за одбегнување блокада


динамички го прегледува графот за алокација
на ресурси за да осигура дека нема да се случи
кружно чекање.

◦ Состојба на доделување ресурси се дефинира


преку бројот на слободни и алоцирани ресурси
и максималните барања на процесот
 Кога на процесот му треба слободен ресурс,
системот мора да одлучи дали неговото доделување
ќе го остави системот во сигурна состојба

 Системот е во сигурна состојба ако постои секвенца


<P1, P2, …, Pn> на СИТЕ процеси во системот така да
за секој Pi, ресурсите кои Pi може сеуште да ги
побара можат да бидат задоволени од тековно
слободните ресурси + ресурсите држени од сите Pj,
со j < i.
 Ова значи:
◦ ако потребите за ресурси на Pi не можат да се остварат
веднаш, тогаш Pi ќе чека додека другите Pj завршат.
◦ кога Pj завршил, Pi може да ги добие потребните ресурси, да
се изврши, да ги врати алоцираните ресурси и за терминира.
◦ кога Pi терминирал, Pi +1 може да ги добие бараните ресурси,
итн
 Состојба се нарекува сигурна, ако таа не е
блокирана и ако постои начин да се задоволат
сите потреби за ресурси кај тековните процеси,
активирајќи ги процесите по некој редослед

 Пр1. За еден ресурс, со 10 инстанци


доделени
потребни
процеси

2
5
4 7
 Систем со еден тип ресурси
 Вкупно 10 инстанци
◦ Втората ситуација е сигурна,
◦ Третата не е сигурна
 ако системот е во сигурна состојба ⇒ нема
блокада
 ако системот е во несигурна состојба ⇒ можност
за блокада
 одбегнување ⇒ осигурај дека системот нема
никојпат да влезе во несигурна состојба
 Ако имаме по една инстанца од секој
ресурс може да користиме граф за
алокација на ресурси

 Ако имаме повеќе инстанци од некој тип


ресурс користиме Банкаров алгоритам
 Поднеси барање за лакот Pi → Rj што значи дека процесот
Pi може да го побара ресурсот Rj; презентирано со
испрекинати линии.

 Лакот за поднесено барање се трансформира во лак за


барање кога процесот ќе го побара ресурсот

 Лакот за барање се претвора во лак за доделување кога


ресурсот му е доделен на процесот

 Кога ресурсот е ослободен од процесот, лакот за


доделување се враќа во лак за поднесување барање

 Ресурсите мора однапред да бидат побарани во системот


 Претпостави дека процесот Pi бара ресурс Rj

 Барањето ќе биде удоволено само ако


конвертирањето на лак за барање во лак за
доделување не резултира во формирање циклус
во графот за алокација на ресурси
Allocation
Need
 Алгоритам за проверка дали состојбата е сигурна
 Да се најде редот во втората матрица чии елементи
се помали или еднакви на A (...редот на процесот D)
 Ако нема таков, следува блокада!
 Ако има, изврши го тој процес и врати ги неговите ресурси
на A
 Повторувај го чекорот додека не се маркирани сите
процеси
 Ако сите се извршат, состојбата била сигурна
 Ако има блокада, состојбата НЕ била сигурна
 Повеќе инстанци од ист тип

 Секој процес мора однапред да знае колку


максимум инстанци од секој ресурс му требаат

 Кога процесот бара ресурс, можеби ќе мора да


чека

 Кога процесот ќе ги добие сите ресурси што му


требаат, мора да ги врати за конечно време
Нека n = број на процеси и m = број на типови ресурси

 Available: Вектор со должина m. Ако available[j] = k, тогаш


постојат k слободни инстанци на ресурсот од тип Rj

 Max: n x m матрица. Ако Max [i,j] = k, тогаш на процесот Pi


може да му требаат најмногу k инстанци од ресурсот од тип Rj.

 Allocation: n x m матрица. Ако Allocation[i,j] = k тогаш на Pi се


тековно алоцирани k инстанци од Rj.
 Need: n x m матрица. Ако Need[i,j] = k, тогаш на Pi може да му
требаат уште k инстанци од Rj за да се заврши
Need [i,j] = Max[i,j] – Allocation [i,j]
Request = вектор на побарувања за процесот Pi. Ако
Requesti [j] = k тогаш процесот Pi бара k инстанци од
ресурсот Rj.
1. Ако Requesti ≤ Needi оди на чекор 2. Инаку,
пријави грешка бидејќи процесот ги достигна
максималните барања
2. Ако Requesti ≤ Available, оди на чекор 3. Инаку Pi
мора да чека, бидејќи ресурсите не му се достапни.
3. Замисли дека му ги додели бараните ресурси на Pi
модифицирајќи ја состојбата според:
Available = Available – Request;
Allocationi = Allocationi + Requesti;
Needi = Needi – Requesti;
 ако е сигурна ⇒ додели ресурси на Pi.
 ако е несигурна ⇒ Pi мора да чека, врати ја состојбата од
пред да ги направиш измените
 5 процеси P0 до P4;
3 типови ресурси:
A (10 инстанци), B (5 инстанци), и C (7 инстанци).
 Во време T0:
Allocation Max Available
ABC ABC ABC
P0 0 1 0 7 5 3 332
P1 2 0 0 3 2 2
P2 3 0 2 9 0 2
P3 2 1 1 2 2 2
P4 0 0 2 4 3 3
 Содржината на матрицата Need е Max – Allocation.

Need Available
ABC ABC
P0 7 4 3 332
P1 1 2 2
P2 6 0 0
P3 0 1 1
P4 4 3 1

 Системот е во сигурна состојба бидејќи секвенцата < P1,


P3, P4, P2, P0> го задоволува условот за сигурност
 Теоретски убаво, но практично бескорисно
◦ Како однапред да го дознаеме бројот на ресурси по
процес?
◦ Бројот на активни процеси динамички се менува, нови
корисници се вклучуваат и исклучуваат!
◦ Некој ресурс може да биде недостапен (расипување и
сл.)!

 Во практиката, многу малку постоечки системи го


користат банкаровиот алгоритам за избегнување
блокади!
 Дозволи ја блокадата
 Анализирај ја ситуацијата
 Одбери процес - жртва и отстрани го
 Направи надоместување (recovery)

 Прашања:
◦ Како да препознаеме дека се случува блокада?
◦ Потребен е формален алгоритам (детектирање циклуси
во ориентиран граф, матричен алгоритам)
 Како да ја одбереме жртвата?
◦ Да се препознае кој од процесите се блокира...
 Направи wait-for граф на чекање
◦ Јазлите се процеси.
◦ Pi → Pj ако Pi го чека Pj.

 Периодично стартувај алгоритам кој бара


циклуси низ графот. Ако има циклус, има
блокада.

 Алгоритам кој детектира циклус во граф има


комплексност од n2 операции, каде n е бројот на
лакови во графот
 Пример:

граф на алокација на ресурси кореспондирачки wait-for граф


 Available: Вектор со должина m означува колкав
број слободни ресурси има од секој тип

 Allocation: n x m матрица која дефинира колкав


број ресурси од ист тип тековно се алоцирани на
секој процес

 Request: n x m матрица која ги означува


тековните барања на секој процес. Ако
Request [ij] = k, тогаш процесот Pi бара уште k
инстанци од ресурсот од тип Rj
1. Нека Work и Finish се вектори со должина m и n,
соодветно. Иницијализирај:
a) Work = Available
b) за i = 1,2, …, n,
ако Allocationi ≠ 0,
тогаш
Finish[i] = false;
инаку,
Finish[i] = true.
2. Најди индекс i така да и двата услова важат:
(a) Finish[i] == false
(b) Requesti ≤ Work

Ако нема таков i, оди на чекор4.


3. Work = Work + Allocationi
Finish[i] = true
оди на чекор 2.

4. Ако Finish[i] == false, за некое i, 1 ≤ i ≤ n, тогаш


системот е во блокада. Уште повеќе, ако
Finish[i] == false, тогаш Pi е блокиран.

На алгоритамов му требаат O(m x n2) операции


да детектира дали системот е во блокада
 Пет процеси P0 до P4; три типови ресурси
A (7 инстанци), B (2 инстанци), и C (6 инстанци).
 Во време T0:
Allocation Request Available
ABC ABC ABC
P0 0 1 0 0 0 0 0
0 1000
P1 2 0 0 2 0 2 313
P2 3 0 3 0 0 0 524
P3 2 1 1 1 0 0 724
P4 0 0 2 0 0 2 726

 Секвенцата <P0, P2, P3, P1, P4> ќе резултира со Finish[i] =


true за сите i.
 P2 бара дополнителна инстанца од типот C.
Request
ABC
P0 000
P1 201
P2 001
P3 100
P4 002

 Состојба на системот?
◦ Може да се добијат ресурсите кои ги држи P0, но нема доволно
ресурси да се исполнат барањата на другите процеси.
◦ Блокада, која се состои од процесите P1, P2, P3, и P4.
 Кога и колку често се вклучува зависи од:
◦ Колку често се случува блокада?
◦ Колку процеси треба да се вратат назад (roll
back)?
 по еден за секој откачен циклус

 Ако алгоритамот за детекција се вклучува


произволно, може да има повеќе циклуси
во графот и да не можеме да одлучиме
кој од нив ја создал блокадата
 Привремено одземи ресурси на некој процес, па после да
му се врати (може при пакетни обработки, зависно е од
ресурсот и ретко е можно)

 Врати некој процес наназад (се запишуваат на диск


состојби на процеси од кои места тие може да се
реактивираат)

 Убиј еден или повеќе процеси (што се во блокада или не)


◦ Добро е да се убие процес кој нема проблеми да се пушти
повторно
◦ (пр. компајлирање, но не ажурурање во база на податоци - ако
на пр. Процесот додава 1 на некој запси и ако потоа тој се
убие, при повторното стартување, ќе додаде уште 1, што е
некоректно)
 Прекини ги сите процеси во блокада

 Прекинувај еден по еден процес сè додека


блокадата не е елиминирана

 По кој редослед да се одбере кој процес да се


прекине?
◦ Приоритет на процеси
◦ Колку долго даден процес се извршувал и уште колку
има до крајот
◦ Ресурси кои процесот ги искористил
◦ Ресурси кои сеуште му требаат на процесот
◦ Колку процеси ќе треба да бидат терминирани
◦ Дали процесот е интерактивен или пакетен (batch)?
 Селектирање жртва – минимизирање цена

 Rollback – врати се во некоја претходна сигурна


состојба, рестартирај го процесот оттаму

 Изгладнување – некој процес може секојпат да


биде биран за жртва, па вклучи го бројот на
враќање на процесот (rollback) како фактор за
цена
 Наједноставен пристап
 Алгоритам на ној (глава во песок)
◦ Колку често се јавува блокадата?
◦ Математичар наспроти инженер!

 Многу системи потенцијално може да страдаат


од блокади
 Во UNIX
◦ потенцијално страда од блокади што не се ни
детектираат
◦ Табела на процеси е конечна величина
◦ Ако fork паѓа бидејќи табелата е полна, треба да се
почека случајно време и да се обиде пак
 Во секој ОС табелите се конечни ресурси и тоа
води кон проблеми
◦ Табели на процеси, конци,
◦ Отворени датотеки
◦ Swap простор на дискот

 Веројатно секој корисник преферира повремена


блокада отколку низа ограничувања во
користењето на ресурсите баланс помеѓу
точноста и удобноста
 Блокадите се потенцијален проблем за секој систем

 Може да се избегнуваат со водење сметка кои состојби се


сигурни (постои низа од настани кои гарантираат дека сите
процеси ќе завршат), а кои не се

 Банкаровиот алгоритам избегнува блокади со не


дозволување на барањето што ќе го доведе системот во
несигурна состојба

 Блокада се избегнува со нумерирање на сите ресурси, т.ш.


сите процеси да ги побаруваат стриктно во растечки
редослед

 Изгладнувањето може да се избегне со FCFS политика

You might also like