# Lista 5 ###### tags: `SO` ## Zadanie 1 **Co robi operacja read(2) i write(2), jeśli bufor rury jest odpowiednio pusty albo pełny?** Pusty: - read : blokuje się Pełny: - write : blokuje się **Jakie gwarancje daje nam operacja write na rurze, do której pisze wiele procesów – każdy z nich wiersze tekstu nie dłuższe niż «PIPE_BUF»?** Gwarancję zapisu atomowego. A i B -> AB lub BA, nigdy A1B1A2B2 **Czemu wszystkie procesy należące do potoku zakończą się bez interwencji powłoki, jeśli co najmniej jeden z nich umrze??** Czytające procesy dostają EOF. (zwijanie w prawo) Procesy piszące dostają SIGPIPE. (zwijanie w lewo) **Kiedy operacje read i write na rurze zwracają „short count”?** Tylko wtedy, kiedy nie ma więcej danych. (potok piszący został zamknięty) **Jak można połączyć rodzica i dziecko rurą, która została utworzona po uruchomieniu dziecka?** ```c= #include "csapp.h" int main(int argc, char *argv[]) { char * myfifo = "/tmp/myfifo"; pid_t pid = Fork(); mkfifo(myfifo, 0666); char buf[10]; int fd; if(pid){ fd = open(myfifo, O_RDONLY); read(fd, buf, 10); buf[9] = '\0'; printf("READ: %s\n", buf); } else{ fd = open(myfifo, O_WRONLY); write(fd,"012345678",9); } close(fd); return EXIT_SUCCESS; } ``` ## Zadanie 2 ## Zadanie 3 ![](https://i.imgur.com/ZpGPPb3.png) Usuwanie - powiększenie entry size Dodanie - znalezienie luki odpowiedniego rozmiaru Kompaktowanie wykonywane jest po osiągnięciu krytycznej ilości nieużytków. ## Zadanie 4 ## Zadanie 5 ## Zadanie 6 ```c= static noreturn void filter_chain(pipe_t in) { long prime; /* TODO: Something is missing here! */ if (!ReadNum(in, &prime)) { CloseReadEnd(in); exit(EXIT_SUCCESS); } printf("%ld\n", prime); pipe_t gen_pipe = MakePipe(); if(Fork()) { /* Parent */ CloseReadEnd(gen_pipe); filter(in, gen_pipe, prime); CloseWriteEnd(gen_pipe); Wait(NULL); } else { /* Child */ CloseWriteEnd(gen_pipe); filter_chain(gen_pipe); } CloseReadEnd(in); exit(EXIT_SUCCESS); } ``` lsof | grep "prime" ## Zadanie 7 ```c= static void Sort(int parent_fd) { int nelem = ReadNum(parent_fd); if (nelem < 2) { WriteNum(parent_fd, ReadNum(parent_fd)); Close(parent_fd); return; } sockpair_t left = MakeSocketPair(); /* TODO: Spawn left child. */ int left_elem = nelem / 2; if(Fork()) { /* Parent */ Close(left.child_fd); } else { /* Child*/ Close(left.parent_fd); Sort(left.child_fd); return; } sockpair_t right = MakeSocketPair(); /* TODO: Spawn right child. */ int right_elem = nelem - left_elem; if(Fork()) { /* Parent */ Close(right.child_fd); } else { /* Child*/ Close(right.parent_fd); Sort(right.child_fd); return; } /* TODO: Send elements to children and merge returned values afterwards. */ SendElem(parent_fd, left.parent_fd, left_elem); SendElem(parent_fd, right.parent_fd, right_elem); Merge(left.parent_fd, right.parent_fd, parent_fd); /* Wait for both children. */ Wait(NULL); Wait(NULL); } ``` ```c= sockpair_t left = MakeSocketPair(); /* TODO: Spawn left child. */ if(!Fork()){ Close(left.parent_fd); Sort(left.child_fd); return; } sockpair_t right = MakeSocketPair(); /* TODO: Spawn right child. */ if(!Fork()){ Close(right.parent_fd); Sort(right.child_fd); return; } int nLeft = nelem / 2; int nRight= nelem - nLeft; Close(left.child_fd); Close(right.child_fd); SendElem(parent_fd,left.parent_fd, nLeft); SendElem(parent_fd,right.parent_fd, nRight); Merge(left.parent_fd,right.parent_fd,parent_fd); ```