230 likes | 402 Views
Rings. CNS 3060. Ring Topology. Each node has one input and one output Information circulates clockwise. 1. 5. 2. Ring structures are attractive because interconnection costs scale linearly. 4. 3. Developing a Ring. // this code shows how to connect the standard input of
E N D
Rings CNS 3060
Ring Topology Each node has one input and one output Information circulates clockwise 1 5 2 Ring structures are attractive because interconnection costs scale linearly. 4 3
Developing a Ring // this code shows how to connect the standard input of // a process to it’s standard output // error handling is not show for brevity and clarity int fd[2]; pipe(fd); dup2(fd[0], STDIN_FINENO); dup2(fd[1], STDOUT_FILENO); close (fd[0]); close (fd[1]); process file descriptor table after pipe call Standard in standard out standard err pipe read pipe write 0 1 2 3 4 2 stderr 1 fd[0] stdin 0 A stdout fd[1] 3 4 pipe read from pipe write to pipe
Developing a Ring // this code shows how to connect the standard input of // a process to it’s standard output // error handling is not show for brevity and clarity int fd[2]; pipe(fd); dup2(fd[0], STDIN_FINENO); dup2(fd[1], STDOUT_FILENO); close (fd[0]); close (fd[1]); The dup2 call does the Following: - Closes standard in • Makes a copy of fd[0] • and stores it in file desc 0. standard in pipe read 0 1 2 3 4 standard out standard err pipe read pipe write 2 stderr 1 fd[0] stdin 0 A stdout fd[1] 3 4 pipe read from pipe write to pipe
Developing a Ring // this code shows how to connect the standard input of // a process to it’s standard output // error handling is not show for brevity and clarity int fd[2]; pipe(fd); dup2(fd[0], STDIN_FINENO); dup2(fd[1], STDOUT_FILENO); close (fd[0]); close (fd[1]); The 2nd dup2 call does the Following: - Closes standard out • Makes a copy of fd[1] • and stores it in file desc 1. pipe read 0 1 2 3 4 pipe write standard out standard err pipe read pipe write 2 stderr 1 fd[0] 0 A stdout fd[1] 3 4 pipe read from pipe write to pipe
Developing a Ring // this code shows how to connect the standard input of // a process to it’s standard output // error handling is not show for brevity and clarity int fd[2]; pipe(fd); dup2(fd[0], STDIN_FINENO); dup2(fd[1], STDOUT_FILENO); close (fd[0]); close (fd[1]); process file descriptor table after close calls pipe read pipe write standard err 0 1 2 2 1 0 A read from pipe write to pipe pipe
Developing a Ring // this code shows how to connect the standard input of // a process to it’s standard output // error handling is not show for brevity and clarity int j, my_int; for (j = 0; j < 10; j++) { write(STDOUT_FILENO, &j, sizeof(i)); read(STDIN_FILENO, &my_int, sizeof(my_int)); fprintf(stderr, “%d\n”, my_int); } process file descriptor table after close calls pipe read pipe write standard err 0 1 2 2 1 0 A pipe
Ring of 2 Processes 2 int fd[2]; pid_t childpid; pipe(fd); dup2(fd[0], STDIN_FILENO); dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); pipe(fd); childpid = fork( ); if (childpid > 0) dup2(fd[1], STDOUT_FILENO); else if (childpid == 0) dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); A 0 1 pipe process A file descriptor table pipe read pipe write standard err 0 1 2
Ring of 2 Processes 2 A int fd[2]; pid_t childpid; pipe(fd); dup2(fd[0], STDIN_FILENO); dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); pipe(fd); childpid = fork( ); if (childpid > 0) dup2(fd[1], STDOUT_FILENO); else if (childpid == 0) dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); 0 4 1 3 pipe a pipe b read from pipe write to pipe process A file descriptor table After creating 2nd pipe pipe a read pipe a write standard err pipe b read pipe b write 0 1 2 3 4 fd[0] fd[1]
Ring of 2 Processes 2 A int fd[2]; pid_t childpid; pipe(fd); dup2(fd[0], STDIN_FILENO); dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); pipe(fd); childpid = fork( ); if (childpid > 0) dup2(fd[1], STDOUT_FILENO); else if (childpid == 0) dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); 0 4 1 3 pipe a pipe b 0 1 3 4 B 2 process B file descriptor table After fork call pipe a read pipe a write standard err pipe b read pipe b write 0 1 2 3 4 fd[0] fd[1]
Ring of 2 Processes 2 1 A int fd[2]; pid_t childpid; pipe(fd); dup2(fd[0], STDIN_FILENO); dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); pipe(fd); childpid = fork( ); if (childpid > 0) dup2(fd[1], STDOUT_FILENO); else if (childpid == 0) dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); 0 4 3 pipe a pipe b 0 1 3 4 B 2 process A file descriptor table after if statement Parent code (A)… pipe a read standard err pipe b read pipe b write 0 1 2 3 4 pipe a write pipe b write fd[0] fd[1]
Ring of 2 Processes 2 1 A int fd[2]; pid_t childpid; pipe(fd); dup2(fd[0], STDIN_FILENO); dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); pipe(fd); childpid = fork( ); if (childpid > 0) dup2(fd[1], STDOUT_FILENO); else if (childpid == 0) dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); 0 4 3 pipe a 0 pipe b 0 1 3 4 B 2 process B file descriptor table After if statement pipe b read pipe a read pipe a write standard err pipe b read pipe b write 0 1 2 3 4 Child code (B) … fd[0] fd[1]
Ring of 2 Processes 2 1 A int fd[2]; pid_t childpid; pipe(fd); dup2(fd[0], STDIN_FILENO); dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); pipe(fd); childpid = fork( ); if (childpid > 0) dup2(fd[1], STDOUT_FILENO); else if (childpid == 0) dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); 0 pipe a 0 pipe b 1 3 4 B 2 process A file descriptor table After close statements pipe a read pipe b write standard err 0 1 2 Both processes execute this code …
Ring of 2 Processes 2 1 A int fd[2]; pid_t childpid; pipe(fd); dup2(fd[0], STDIN_FILENO); dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); pipe(fd); childpid = fork( ); if (childpid > 0) dup2(fd[1], STDOUT_FILENO); else if (childpid == 0) dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); 0 0 pipe a pipe b 1 B 2 process B file descriptor table After close statements pipe b read pipe a write standard err 0 1 2 Both processes execute this code …
std error 2 read from pipe 1 A read from pipe 0 write to pipe 0 pipe a pipe b 1 write to pipe B 2 std error
Generalize the algorithm so that it generates a ring with n nodes … Process connects it’s stdin to its stdout Process creates a new pipe and forks parent child Connect pipes Connect pipes Break out of loop done
Token Ring Tokens are used in Ring topologies to grant exclusive rights to some shared resource (the ring). When a given node acquires the token, it has exclusive access to the shared resource. When the process is done with the resource, it gives up the token so that some other node can pick it up. This is similar to the speaking stick used in some cultures to enforce order at meetings. Only the person holding the stick can speak.
In this case, we will simulate a very simple token passing token passing scheme to grant exclusive use of standard error among a ring of processes. • The process starts when the first process writes a token (a single character) to it’s standard output. From then on, each process in turn • Reads the token from it’s standard input • If it has data to write, it holds the token while it writes • to standard error (the shared resource) • It then writes the token to it’s standard output
std error 2 read from pipe 1 A read from pipe 0 write to pipe 0 pipe a pipe b 1 write to pipe B 2 std error Some data o o o o
Some data o o o o std error 2 read from pipe 1 A read from pipe 0 write to pipe 0 pipe a pipe b 1 write to pipe B 2 std error
After writing it’s output, a process can’t terminate. It must continue passing the token until all of the processes in the ring are done. When all of the processes in the ring have finished writing their output, the program can end. Suggest an approach to handle this….
Final Project Option #1 • Write a program that creates a ring of n processes. • pass a token around the ring to enforce mutual exclusion. • Vary the number of times each process writes it’s message • to standard out by having each process repeat the critical • section some random number of times between 0 and r. • The value of r will come as a parameter from the command line. • Read the token • Call the function prtastr( ) to write one output message • Write the token • When done outputting all of its messages, a process will just • pass the token. When all processes are done, terminate the • program.