Computation structures. Support for problem-solving lesson #7

Similar documents
Inter-Process Communication: Message Passing. Thomas Plagemann. Big Picture. message passing communication?

Prepared by Prof. Hui Jiang (COSC3221) 2/9/2007

INTER-PROCESS COMMUNICATION. UNIX Programming 2015 Fall by Euiseong Seo

Lecture 8: Inter-process Communication. Lecturer: Prof. Zichen Xu

Dept. of CS, York Univ. 1

UNIX IPC. Unix Semaphore Unix Message queue

CSE 120. Fall Lecture 6: Semaphores. Keith Marzullo

INTER-PROCESS COMMUNICATION Tanzir Ahmed CSCE 313 Fall 2018

Message Queues, Semaphores, Shared Memory

MC7412 NETWORK PROGRAMMING LABORATORY L T P C

CSci 4061 Introduction to Operating Systems. IPC: Message Passing, Shared Memory

Synchronization Classic Problems

Message Queues POSIX

Synchronization. Peter J. Denning CS471/CS571. Copyright 2001, by Peter Denning

COP 4225 Advanced Unix Programming. Synchronization. Chi Zhang

Lecture 20. Log into Linux. Copy directory /home/hwang/cs375/lecture20 Project 5 due today. Project 6 posted, due Tuesday, April 8. Questions?

경희대학교컴퓨터공학과 조진성. UNIX System Programming

CS 385 Operating Systems Fall 2013 Homework Assignment 2 Inter-Process Communications and Synchronization

Computation structures. Support for problem-solving lesson #6

Parallel And Distributed Compilers

CS 385 Operating Systems Spring 2013 Homework Assignment 2 Third Draft Inter-Process Communications and Synchronization

Prof. Hui Jiang Dept of Computer Science and Engineering York University

CS 385 Operating Systems Fall 2011 Homework Assignment 5 Process Synchronization and Communications

CS370 Operating Systems

Process Coordination

Synchronization. Race Condition. The Critical-Section Problem Solution. The Synchronization Problem. Typical Process P i. Peterson s Solution

Chapter 5: Process Synchronization. Operating System Concepts Essentials 2 nd Edition

CS 361 Computer Systems Fall 2017 Homework Assignment 4 - Inter-Process Communications & I/O

ECE264 Spring 2013 Final Exam, April 30, 2013

CS 471 Operating Systems. Yue Cheng. George Mason University Fall 2017

ECE264 Fall 2013 Exam 1, September 24, 2013

Programmation Système Cours 10 System V IPC

UNIX Input/Output Buffering

Assignment #2. Problem 2.1: airplane synchronization

Process Synchronization

Operating Systems. Lecture 8

Semaphores. To avoid busy waiting: when a process has to wait, it will be put in a blocked queue of processes waiting for the same event

Semaphores. Semaphores. Semaphore s operations. Semaphores: observations

Interprocess Communication. Originally multiple approaches Today more standard some differences between distributions still exist

ECE264 Spring 2013 Exam 1, February 14, 2013

Learning Outcomes. Concurrency and Synchronisation. Textbook. Concurrency Example. Inter- Thread and Process Communication. Sections & 2.

COMP 2355 Introduction to Systems Programming

Concurrency and Synchronisation

Interprocess Communication. Bosky Agarwal CS 518

Håkan Sundell University College of Borås Parallel Scalable Solutions AB

#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *stat_loc); pid_t waitpid(pid_t pid, int *stat_loc, int options);

Concurrency and Synchronisation

CSE Traditional Operating Systems deal with typical system software designed to be:

Process Synchronization

Concept of a process

Pipes. Pipes Implement a FIFO. Pipes (cont d) SWE 545. Pipes. A FIFO (First In, First Out) buffer is like a. Pipes are uni-directional

CSE 333 Lecture 16 - network programming intro

Lecture 6 (cont.): Semaphores and Monitors

Chapter 7: Process Synchronization. Background

Synchronization Basic Problem:

Compile and execute fifo1.cpp listed above. Try the Balady's anomaly examples discussed in class. Did you observe the Belady's anomaly?

CS 153 Design of Operating Systems Winter 2016

CS 6400 Lecture 11 Name:


Chapter 7: Process Synchronization. Background. Illustration

CSPP System V IPC 1. System V IPC. Unix Systems Programming CSPP 51081

Note: The following (with modifications) is adapted from Silberschatz (our course textbook), Project: Producer-Consumer Problem.

ECE264 Summer 2013 Exam 1, June 20, 2013

CS370 Operating Systems

Reading compiler errors

10th Slide Set Operating Systems

Lecture Topics. Announcements. Today: Concurrency (Stallings, chapter , 5.7) Next: Exam #1. Self-Study Exercise #5. Project #3 (due 9/28)

Operating Systems. Synchronization, part 3 Monitors, classical sync. problems

Synchronization. CS 475, Spring 2018 Concurrent & Distributed Systems

System Programming. Pipes I

Process Synchronization: Semaphores. CSSE 332 Operating Systems Rose-Hulman Institute of Technology

Multitasking / Multithreading system Supports multiple tasks

ENGR 3950U / CSCI 3020U UOIT, Fall 2012 Quiz on Process Synchronization SOLUTIONS

Lesson 6: Process Synchronization

EI 338: Computer Systems Engineering (Operating Systems & Computer Architecture)

CS631 - Advanced Programming in the UNIX Environment Interprocess Communication I

UNIT 7 INTERPROCESS COMMUNICATION

CS Operating Systems

CS Operating Systems

Chapter 5: Process Synchronization. Operating System Concepts 9 th Edition

C programming for beginners

Important Dates. October 27 th Homework 2 Due. October 29 th Midterm

Lecture 5 Threads and Pthreads II

CS3733: Operating Systems

EE458 - Embedded Systems Lecture 8 Semaphores

Synchronization II. q Condition Variables q Semaphores and monitors q Some classical problems q Next time: Deadlocks

High-level Synchronization

Pre-lab #2 tutorial. ECE 254 Operating Systems and Systems Programming. May 24, 2012

Lecture 3 SPIN and Promela

518 Lecture Notes Week 3

CS370 Operating Systems Midterm Review

Unix-Linux 2. Unix is supposed to leave room in the process table for a superuser process that could be used to kill errant processes.

ECE264 Fall 2013 Exam 3, November 20, 2013

Synchronization Primitives

The C Programming Language

COP 4604 UNIX System Programming IPC. Dr. Sam Hsu Computer Science & Engineering Florida Atlantic University

Process Synchronization

struct ipc_perm sem_perm; ushort sem_nsems; /* count of sems in set */ time_t sem_otime; /* last operation time */

Networking Operating Systems (CO32010)

More Synchronization; Concurrency in Java. CS 475, Spring 2018 Concurrent & Distributed Systems

Transcription:

Computation structures Support for problem-solving lesson #7

Exercise 1 Give an implementation of the mutual exclusion between 2 processes using only the blocking message queues of size 0 as synchronization mechanism.

Exercise 1 Recall A blocking message queue of size 0 means that: q?x will block the calling process until another process executes q!x; Symmetrically, q!x will block the calling process until another process executes q?x. Blocking message queues of size 0 are an abstract concept They are not directly implemented (at least, not using System V). They can, however, be implemented using semaphores. shared semaphore sreceive = 0, ssend = 0; q!x signal(sreceive); wait(ssend); q?x signal(ssend); wait(sreceive); Does not consider the message x. See slide 248 for a complete example.

Exercise 1 What you should not do: #define wait 0 #define signal 1 shared chan q[0]; //Process 1 //Process 2 q?wait; q?signal; Why isn't this good? - This is not mutual exclusion. This is Rendez-vous. Both processes will wait each other before and after the critical section (and both will thus be able to execute instructions in the critical section). - How would you scale this to a mutual exclusion with N > 2 processes?

Exercise 1 Each process should execute the same code (to be scalable) #define wait 0 #define signal 1 shared chan q[0]; //Process 1 //Process 2 But now, each process is blocked. How can I get out of the deadlock?

Exercise 1 Each process should execute the same code (to be scalable) #define wait 0 #define signal 1 shared chan q[0]; //Process 1 //Process 2 //Process 3 int value = 0; if(value == 0) { q?wait; value = 1; else { q?signal; value = 0; But now, each process is blocked. How can I get out of the deadlock? By addind an "unlocker" process.

Exercise 1 Let's convince ourselves that this works, by using a possible interleaving. //Process 1 #define wait 0 #define signal 1 shared chan q[0]; //Process 2 //Process 3 int value = 0; if(value == 0) { q?wait; value = 1; else { q?signal; value = 0; Process 1 gets the hand, and tries to enter the critical section. It is blocked on the q!wait operation.

Exercise 1 Let's convince ourselves that this works, by using a possible interleaving. //Process 1 #define wait 0 #define signal 1 shared chan q[0]; //Process 2 //Process 3 int value = 0; if(value == 0) { q?wait; value = 1; else { q?signal; value = 0; Process 3 gets the hand, and unlocks Process 1 thanks to the q?wait operation. It is also free to continue.

Exercise 1 Let's convince ourselves that this works, by using a possible interleaving. //Process 1 #define wait 0 #define signal 1 shared chan q[0]; //Process 2 //Process 3 int value = 0; if(value == 0) { q?wait; value = 1; else { q?signal; value = 0; Process 3 makes another loop, but is blocked on the q?signal operation.

Exercise 1 Let's convince ourselves that this works, by using a possible interleaving. //Process 1 #define wait 0 #define signal 1 shared chan q[0]; //Process 2 //Process 3 int value = 0; if(value == 0) { q?wait; value = 1; else { q?signal; value = 0; Process 2 takes the hand, but is blocked on the q!wait operation.

Exercise 1 Let's convince ourselves that this works, by using a possible interleaving. //Process 1 #define wait 0 #define signal 1 shared chan q[0]; //Process 2 //Process 3 int value = 0; if(value == 0) { q?wait; value = 1; else { q?signal; value = 0; Process 1 is thus the only one that can proceed, and also the only one that can enter the critical section. It will unlock Process 3 when executing the q!signal operation, and Process 2 will get a chance to enter the critical section.

System V From theory to practice Using system V message queues requires an additional include: <sys/msg.h> It also requires a structure to store the messages struct mymsgbuf { long mtype; char mtext[max_send_size]; //Be careful about the terminating '0' ; Creating a message queue: int msgget ( key_t key, int msgflg ); Posting a message: int msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg ); Reading a message: int msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long mtype, int msgflg ); Other operations on queues : int msgctl (int msgqid, int cmd, struct msqid_ds *buf );

Exercise 2 Consider the following programs: 1 #include <stdio.h> #include <stdlib.h> #include <sys/msg.h> 2 /** reuse lines 1...11 of receiver **/ int main(int argc, char ** argv) { 6 11 16 21 26 #define MSGLEN 128 #define KEY 345782 struct { long mtype; char buf[msglen]; msg; int main() { int qid; if((qid =msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); if (msgrcv(qid,&msg,msglen,1,0) < 0) die("failed to receive"); printf("got '%s'\n",msg.buf); if(msgctl(qid,ipc_rmid,0) < 0) die("warning : trailing queue"); return EXIT_SUCCESS; 7 12 17 22 27 if (argc!= 2) { fprintf(stderr, "Usage : %s <message>\n", argv[0]); return EXIT_FAILURE; int qid; if ((qid=msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); msg.type = 1; strncpy(msg.buf, argv[1], MSGLEN); if(msgsnd(qid,&msg,msglen,0) < 0) die("failed to send"); return EXIT_SUCCESS; int die(char *msg) { perror(msg); exit(exit_failure); Can they be used to implement a Rendez-vous between two scripts?

Exercise 2 Can they be used to implement a Rendez-vous between two scripts? 1 #include <stdio.h> #include <stdlib.h> #include <sys/msg.h> 2 /** reuse lines 1...11 of receiver **/ int main(int argc, char ** argv) { 6 11 16 21 26 #define MSGLEN 128 #define KEY 345782 struct { long mtype; char buf[msglen]; msg; int main() { int qid; if((qid =msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); if (msgrcv(qid,&msg,msglen,1,0) < 0) die("failed to receive"); printf("got '%s'\n",msg.buf); if(msgctl(qid,ipc_rmid,0) < 0) die("warning : trailing queue"); return EXIT_SUCCESS; 7 12 17 22 27 if (argc!= 2) { fprintf(stderr, "Usage : %s <message>\n", argv[0]); return EXIT_FAILURE; int qid; if ((qid=msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); msg.type = 1; strncpy(msg.buf, argv[1], MSGLEN); if(msgsnd(qid,&msg,msglen,0) < 0) die("failed to send"); return EXIT_SUCCESS; int die(char *msg) { perror(msg); exit(exit_failure); Not really. The receiver will wait until the sender sent something, but the reverse is not true.

Exercise 3 Consider the following programs: 1 #include <stdio.h> #include <stdlib.h> #include <sys/msg.h> 2 /** reuse lines 1...11 of receiver **/ int main(int argc, char ** argv) { 6 11 16 21 26 #define MSGLEN 128 #define KEY 345782 struct { long mtype; char buf[msglen]; msg; int main() { int qid; if((qid =msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); if (msgrcv(qid,&msg,msglen,1,0) < 0) die("failed to receive"); printf("got '%s'\n",msg.buf); if(msgctl(qid,ipc_rmid,0) < 0) die("warning : trailing queue"); return EXIT_SUCCESS; 7 12 17 22 27 if (argc!= 2) { fprintf(stderr, "Usage : %s <message>\n", argv[0]); return EXIT_FAILURE; int qid; if ((qid=msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); msg.type = 1; strncpy(msg.buf, argv[1], MSGLEN); if(msgsnd(qid,&msg,msglen,0) < 0) die("failed to send"); return EXIT_SUCCESS; int die(char *msg) { perror(msg); exit(exit_failure); Modify the above programs in order to design a reader and a writer that communicate through a message queue: The writer sends messages coming from the standard input (stdin) on the queue and ends by sending the "." symbol. The reader displays the messages from the queue on the standard output (stdout) and stops when it receives the "." symbol.

Exercise 3 Modify the program ( ) 1 #include <stdio.h> #include <stdlib.h> #include <sys/msg.h> 2 /** reuse lines 1...11 of receiver **/ int main(int argc, char ** argv) { 6 11 16 21 26 #define MSGLEN 128 #define KEY 345782 struct { long mtype; char buf[msglen]; msg; int main() { int qid; if((qid =msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); if (msgrcv(qid,&msg,msglen,1,0) < 0) die("failed to receive"); printf("got '%s'\n",msg.buf); if(msgctl(qid,ipc_rmid,0) < 0) die("warning : trailing queue"); return EXIT_SUCCESS; 7 12 17 22 27 if (argc!= 2) { fprintf(stderr, "Usage : %s <message>\n", argv[0]); return EXIT_FAILURE; int qid; if ((qid=msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); msg.type = 1; strncpy(msg.buf, argv[1], MSGLEN); if(msgsnd(qid,&msg,msglen,0) < 0) die("failed to send"); return EXIT_SUCCESS; int die(char *msg) { perror(msg); exit(exit_failure); Original programs

Exercise 3 Modify the program ( ) 1 #include <stdio.h> #include <stdlib.h> #include <sys/msg.h> 2 /** reuse lines 1...11 of receiver **/ int main(int argc, char ** argv) { 6 11 16 21 26 #define MSGLEN 128 #define KEY 345782 struct { long mtype; char buf[msglen]; msg; int main() { int qid; if((qid =msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); do { if (msgrcv(qid,&msg,msglen,1,0) < 0) die("failed to receive"); printf("got '%s'\n",msg.buf); while(strcmp(msg.buf,".")!= 0); if(msgctl(qid,ipc_rmid,0) < 0) die("warning : trailing queue"); return EXIT_SUCCESS; 7 12 17 22 27 /* if (argc!= 2) { fprintf(stderr, "Usage : %s <message>\n", argv[0]); return EXIT_FAILURE; */ int qid; if ((qid=msgget(key,ipc_creat 0666)) < 0) die("could not access the queue"); msg.type = 1; do { fgets(msg.buf,msglen,stdin); if(msgsnd(qid,&msg,msglen,0) < 0) die("failed to send"); while(strcmp(msg.buf,".")!= 0); return EXIT_SUCCESS; int die(char *msg) { perror(msg); exit(exit_failure); Updated programs

Exercise 4 Simulate a message queue using only semaphores and shared memory. For simplicity, we consider the case of only two processes sending each other integer values as messages.

Exercise 4 Our implementation has to respect the semantics of the message queue: The queue has a finite size (N). When sending on a full queue, the sender must be blocked. When receiving from an empty queue, the receiver must be blocked. There must effectively be a message passing (the reader must be able to receive and read what the writer sent, in order, without any message loss). But the authorized simplifications make the problem easier: Only two processes no need for message type. Only integers no need for character string trimming.

Exercise 4 Let's first start without any synchronization. shared int queue[n]; int in = 0; int readfromqueue() { int rc = queue[in]; in = (in+1)%n int out = 0; void posttoqueue(int val) { queue[out] = val; out = (out+1)%n return rc;

Exercise 4 The reader must be blocked if the queue is empty. shared int queue[n]; shared semaphore empty = 0; int in = 0; int readfromqueue() { wait(empty); int rc = queue[in]; in = (in+1)%n return rc; int out = 0; void posttoqueue(int val) { queue[out] = val; out = (out+1)%n signal(empty);

Exercise 4 The writer must be blocked if the queue is full. shared int queue[n]; shared semaphore empty = 0; shared semaphore full = N; int in = 0; int readfromqueue() { wait(empty); int rc = queue[in]; in = (in+1)%n signal(full); return rc; int out = 0; void posttoqueue(int val) { wait(full); queue[out] = val; out = (out+1)%n signal(empty);