0% found this document useful (0 votes)
3 views

os-lab-notes

The document provides detailed notes on operating system laboratory exercises at Lovely Professional University, covering Linux commands, file permissions, process management, and threading concepts. It includes examples of using system calls like fork(), pthread_create, and mutex locks for synchronization. Additionally, it discusses race conditions and the importance of managing shared resources in multi-threaded environments.

Uploaded by

eykwtjnjw
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

os-lab-notes

The document provides detailed notes on operating system laboratory exercises at Lovely Professional University, covering Linux commands, file permissions, process management, and threading concepts. It includes examples of using system calls like fork(), pthread_create, and mutex locks for synchronization. Additionally, it discusses race conditions and the importance of managing shared resources in multi-threaded environments.

Uploaded by

eykwtjnjw
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

lOMoARcPSD|52877967

OS lab notes

operating system laboratory (Lovely Professional University)

Scan to open on Studocu

Studocu is not sponsored or endorsed by any college or university


Downloaded by Mr.x ([email protected])
lOMoARcPSD|52877967

OS lab notes

whoami
date
cal
man touch
blue directory
white regular text file
red compressed file
green any file/ directory having complete read, write and execute permissions
linux is powerful commnd oriented OS
touch a{1..100}.txt -- for creating 100 files all together
ls a{1..3}.txt
touch comman is basically used to change the timestamp
cp months.txt f1.txt
rm -rf animals (recursively forcefully delete directory)

Both root and normal users are termed as Users.

Root means any system account that has complete system priviledges, complete
permissions to use that system

Ls –a
Ls –i
Ls –d
Ls –l
Man ls

# is used to refer to root account

permissions
admin////root
normal///ordinary

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

read r
write w
execute x

owner u
group g
others o
chmod (ways of changing permissions)

symbolically
Add +
revoke -

numerically/octal
r4
w2
x1

touch tiger
ls 3l tiger
-rw 3rw 3 r41 (1 means links hardlink, soft link)
Chmod u+x tiger (means giving execute to the owner)
Chmod u-w,g-w tiger (revoke write permission from owner and group)
Chmod ug-w tiger (same as above)

Chmod u+w, o-r (give write permission to owner and revoke read permission from others)

Man means manual command

Man write –

Man Man… the command is divided into various section

Section 1 for general commands

Section 2 is for system calls

It is mandatory to use section number with man like <man 2 lseek=. Because if we write man lseek, it will
give details of lseek as a command, but when we write section number it will show lseek as a system call.

File descriptor- uniquely defines the file inspite of their names

3 types-

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

0 means read
1 means Display on device, write
anything else error

write (file descriptor value, <string=, size )

for writing we can use any editor- vim, nano, gedit

nano write.c
#include <unistd.h>
Int main()
{
write (1, <lovely=, 6);
}
Ctrl + X , then y, then enter
Gcc write.c (compilation)
./a.out (output)

In case I want to create a customized name for file rather than a.out, we can use the
command:
Gcc –o r read.c {r is the alias for read.c}
So it will execute with < ./r> in place of ./a.out

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

We work with files, so either we read from file or write into file
Option 1 – I m writing in an existing file with some data written into it.
Option 2- I m creating a new file from scratch

EXisting file will take 2 parameters. 1 is path or file name, 2nd is flag – read or write or both

Creating a file takes 3 parameters, first 2 are same, third is permissions

Vim open.c

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

File descriptor needs a number to be returned whenever a file opens which returns a
number that is associated with that existing file. Fd is an integer

:wq

In case we try to read from a file and write into a file that does not exist.

Open behaves in two ways… it creates the file that doesn’t exist and then opens it!

Pipe sign means whatever is output of left of pipe will be passed as input to whatever written on right
side of pipe.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Overall open will return negative if file doesn’t exist but flag 0_WRONLY will have value 1 if file doesn’t
exist which will pass to O_CREAT.

If I want to see the output on screen, I ll write:

write(1, buf, n);

In case the file exists, and we are writing into the file, the data will overwrite the previous data.

In order to append to the previous data, we will use the flag O_APPEND.

LSEEK

REPOSITION THE cursor position in the file.

lseek(fd, offset, whence)

offset- number of characters you want to move: negative or positive

positions of whence

Fseek(fd,5, SEEK_SET) moves 5 positions from start position

Fseek(fd,5, SEEK_CUR) moves 5 positions from current position foward

Fseek(fd,-5, SEEK_CUR) moves 5 positions from current position Backwards

Fseek(fd,-5, SEEK_END) moves 5 positions from End position Backwards, so we ll always use negative
with SEEK_END.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Now in this program we are reading 10 characters from the file and displaying them on the screen. Then
the cursor will move to 10 position, then again read next 10 characters and display on screen.

Read 10 characters and display it on screen. Use lseek to skip 5 characters and the read next 10
characters.

When process calls fork() system call, a child process is created, means it duplicates the parent process.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Purpose of child process- address space is different, time saving by giving extra task to child, so both
processes are running.

getpid() – get process id

getppid() – get parent process id

fork() returns

<0 failure

0 success of child process creation

>0 returns a parent id to the parent to acknowledge the parent process.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Here at last the parent id is different because it is the id of grandparent as no process stands alone.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Processes can execute in any order. In order to make child execute first, we let the parent process wait
by using wait() function. Now parent will wait for termination until child process executes.

Orphan process:

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Zombie

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

19 May 2022

THREADS

Light weight process means it shares the data and the code of the process in which it runs. So thread
takes fewer resources and utilizes the resources of the process.

Whenever a thread is created it executes a function. A function speeds up the operating speed.
Whenever a function executes a thread executes in parallel, once its done it returns the control back to
the process in which its running.

Every process is an individually entity with its own resources like memory, stack, etc, thread always run
inside a process.

Whenever we create a thread, a system call is there : pthread_create, p stands for POSIX which is a
library. <pthread.h> is the associated header fle.

Pthread is a variable of thread type

Attributes are usually kept NULL.

3rd variable – function associated with thread

4th – arguments

Compilation with –pthread. Eg gcc –pthread th.c

After the thread is created we don’t want process to come before thread finishes, so we make the
function main to wait. .. using pthread_join

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

The pointer value that is returned from the thread and given to the program code, but we usually keep it
NULL.

Programs:

//1. thread creation

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
void *thread_function()
{
printf("test from function\n");
}
int main(){
pthread_t t1;
pthread_create(&t1,NULL,&thread_function, NULL);
pthread_join(t1,NULL);
return 0;
}

Here pthread_t is a data type. [Every thread has its own stack so when its executing its pointing to some
memory location of the stack and the value is passed by address- call by address concept].

If there are multiple thread then we need to use in function in all threads so that the process will wait
until all threads are executed.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Here both the threads t1 and t2 are executing the same function but twice.

// 2. two thread in same program

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
void *thread_function()
{
printf("test from function\n");
//sleep(3);
printf("End of function\n");
}
int main(){
pthread_t t1,t2;
pthread_create(&t1,NULL,&thread_function, NULL);
pthread_create(&t2,NULL,&thread_function, NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}

// Program 3: Program to create threads in linux. Thread prints 0-4 while the main process prints
20-24

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

void *thread_function(void *arg);


int i,j;
int main() {
pthread_t a_thread; //thread declaration

pthread_create(&a_thread, NULL, thread_function, NULL);


//thread is created
pthread_join(a_thread, NULL); //process waits for thread to finish . //Comment this line to see
the difference
printf("Inside Main Program\n");
for(j=20;j<25;j++)
{
printf("%d\n",j);
sleep(1);
}
}

void *thread_function(void *arg) {


// the work to be done by the thread is defined in this function
printf("Inside Thread\n");
for(i=0;i<5;i++)
{
printf("%d\n",i);
sleep(1);
}
}

Difference between sleep and wait… explain!

Sleep is like delay for the function itself. But wait makes other process to wait and join only after the
current thread completes.

RACE condition It is situation where multiple threads try to manipulate or access shared data,
which lead to inconsistencies.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Considering s as a global shared variable, accessed by both threads.. may lead to inconsistent
results. Now the result will depend on which thread executes first and which thread shows the
result first! So synchronization required.

/* Program to show the race condition.


Program to create two threads: one to increment the value of a shared variable and second to
decrement the value of shared variable. Both the threads are executed, so the final value of
shared variable should be same as its initial value. But due to race condition it would not be
same. */

#include<pthread.h>
#include<stdio.h>
#include<unistd.h>
void *fun1();
void *fun2();
int shared=1; //shared variable
int main()
{
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, fun1, NULL);
pthread_create(&thread2, NULL, fun2, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2,NULL);
printf("Final value of shared is %d\n",shared); //prints the last updated value of shared variable
}

void *fun1()
{
int x;
x=shared;//thread one reads value of shared variable
printf("Thread1 reads the value of shared variable as %d\n",x);
x++; //thread one increments its value
printf("Local updation by Thread1: %d\n",x);

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

sleep(1); //thread one is preempted by thread 2


shared=x; //thread one updates the value of shared variable
printf("Value of shared variable updated by Thread1 is: %d\n",shared);
}

void *fun2()
{
int y;
y=shared;//thread two reads value of shared variable
printf("Thread2 reads the value as %d\n",y);
y--; //thread two increments its value
printf("Local updation by Thread2: %d\n",y);
sleep(1); //thread two is preempted by thread 1
shared=y; //thread one updates the value of shared variable
printf("Value of shared variable updated by Thread2 is: %d\n",shared);
}

SYNCHRONIZATION

Program for Process Synchronization using mutex locks

#include<pthread.h>
#include<stdio.h>
#include<unistd.h>
void *fun1();
void *fun2();
int shared=1; //shared variable
pthread_mutex_t l; //mutex lock
int main()
{
pthread_mutex_init(&l, NULL); //initializing mutex locks
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, fun1, NULL);
pthread_create(&thread2, NULL, fun2, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2,NULL);
printf("Final value of shared is %d\n",shared); //prints the last updated value of shared variable
}
void *fun1()
{
int x;
printf("Thread1 trying to acquire lock\n");
pthread_mutex_lock(&l); //thread one acquires the lock. Now thread 2 will not be able to
acquire the lock //until it is unlocked by thread 1
printf("Thread1 acquired lock\n");
x=shared;//thread one reads value of shared variable
printf("Thread1 reads the value of shared variable as %d\n",x);
x++; //thread one increments its value
printf("Local updation by Thread1: %d\n",x);
sleep(1); //thread one is preempted by thread 2
shared=x; //thread one updates the value of shared variable
printf("Value of shared variable updated by Thread1 is: %d\n",shared);

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

pthread_mutex_unlock(&l);
printf("Thread1 released the lock\n");
}
void *fun2()
{
int y;
printf("Thread2 trying to acquire lock\n");
pthread_mutex_lock(&l);
printf("Thread2 acquired lock\n");
y=shared;//thread two reads value of shared variable
printf("Thread2 reads the value as %d\n",y);
y--; //thread two increments its value
printf("Local updation by Thread2: %d\n",y);
sleep(1); //thread two is preempted by thread 1
shared=y; //thread one updates the value of shared variable
printf("Value of shared variable updated by Thread2 is: %d\n",shared);
pthread_mutex_unlock(&l);
printf("Thread2 released the lock\n");
}

Before any executions on shared variable, we will apply the lock using pthread_mutex_lock,
and we pass the lock variable as argument.

Downloaded by Mr.x ([email protected])


lOMoARcPSD|52877967

Second argument is number of processes sharing a semaphore. Here its 0 because it’s the same
process, no inter-process communication is there.

Initial value of any process using semaphores should be 1. (its in binary)

Sem_post means release lock. (It is similar to signal.)

Downloaded by Mr.x ([email protected])

You might also like