diff --git a/OSs/lab2/unix/README.txt b/OSs/lab2/unix/README.txt new file mode 100644 index 0000000..80ba18a --- /dev/null +++ b/OSs/lab2/unix/README.txt @@ -0,0 +1,3 @@ +Данная лабораторная работа разделена на 2 части. В данном случае я обе +постарался сделать на максимум. Однако прочитайте формулировки заданий, чтобы +не совсем плавать при сдаче diff --git a/OSs/lab2/unix/part-A/Makefile b/OSs/lab2/unix/part-A/Makefile new file mode 100644 index 0000000..99ee343 --- /dev/null +++ b/OSs/lab2/unix/part-A/Makefile @@ -0,0 +1,17 @@ +targets = father son +all: $(targets) + +father: father.o + $(CC) -o $@ $^ $(CFLAGS) + +son: son.o + $(CC) -o $@ $^ $(CFLAGS) + +%.o: %.c + $(CC) -c $^ -o $@ $(CFLAGS) + +clean: + rm -f $(targets) + rm -f *.o + rm -f task_dump* + rm -f task* diff --git a/OSs/lab2/unix/part-A/README.txt b/OSs/lab2/unix/part-A/README.txt new file mode 100644 index 0000000..4b2a561 --- /dev/null +++ b/OSs/lab2/unix/part-A/README.txt @@ -0,0 +1,4 @@ +Чтобы продемонстрировать работу лабораторки достаточно запустить lab.sh как +скрипт. Он соберет проект и запустит его для трех пунктов задания. При этом он +сложит вывод программы в файлы task0, task1 и task2, а вывод `ps xf` в +task_dump-0, task_dump-1 и task_dump-2 соотвественно diff --git a/OSs/lab2/unix/part-A/common.h b/OSs/lab2/unix/part-A/common.h new file mode 100644 index 0000000..49fe5a7 --- /dev/null +++ b/OSs/lab2/unix/part-A/common.h @@ -0,0 +1,16 @@ +/* + * "THE CHEESE-WARE LICENSE" (Revision 1): + * wrote this file. As long as you retain this notice + * you can do whatever you want with this stuff. If we meet some day, + * and you think this stuff is worth it, you can buy me some cheese + * in return + */ + +#ifndef COMMON_H_ +#define COMMON_H_ + +#define WAIT_FOR_CHILD 0 +#define DONT_WAIT_FOR_CHILD 1 +#define ZOMBIE_PROCESS 2 + +#endif diff --git a/OSs/lab2/unix/part-A/father.c b/OSs/lab2/unix/part-A/father.c new file mode 100644 index 0000000..71ed66f --- /dev/null +++ b/OSs/lab2/unix/part-A/father.c @@ -0,0 +1,56 @@ +/* + * "THE CHEESE-WARE LICENSE" (Revision 1): + * wrote this file. As long as you retain this notice + * you can do whatever you want with this stuff. If we meet some day, + * and you think this stuff is worth it, you can buy me some cheese + * in return + */ + +#include +#include +#include +#include +#include + +#include "common.h" + +#define PROG_PREFIX "father: " +#define log(fmt, args...) printf(PROG_PREFIX fmt "\n", ##args) + +#define CMD_SIZE 256 + +int main(int argc, const char **argv) +{ + if (argc != 2) { + log("Wrong program usage. 1 argument shuld be passed - program mode"); + log("%d - wait for child", WAIT_FOR_CHILD); + log("%d - father doesn't wait for child", DONT_WAIT_FOR_CHILD); + log("%d - father doesn't wait for child, but child finishes", + ZOMBIE_PROCESS); + return EXIT_FAILURE; + } + long mode = strtol(argv[1], NULL, 10); + if (fork() == 0) { + execl("son", "son", argv[1], NULL); + } + char cmd[CMD_SIZE] = {0}; + snprintf(cmd, CMD_SIZE, "ps fx > task_dump-%ld", mode); + if (mode == WAIT_FOR_CHILD) { + system(cmd); + int status = 0; + int ret = wait(&status); + if (ret < 0) { + log("waiting for son ended with error code %d", ret); + return EXIT_FAILURE; + } + } else if (mode == DONT_WAIT_FOR_CHILD) { + system(cmd); + } else if (mode == ZOMBIE_PROCESS) { + sleep(2); + system(cmd); + } else { + log("Invalid argument. No mode correspoiding to %ld", mode); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/OSs/lab2/unix/part-A/lab.sh b/OSs/lab2/unix/part-A/lab.sh new file mode 100755 index 0000000..e7dc95d --- /dev/null +++ b/OSs/lab2/unix/part-A/lab.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +make -j$(nproc) + +./father 0 > task0 +./father 1 > task1 +./father 2 > task2 diff --git a/OSs/lab2/unix/part-A/son.c b/OSs/lab2/unix/part-A/son.c new file mode 100644 index 0000000..d1ec717 --- /dev/null +++ b/OSs/lab2/unix/part-A/son.c @@ -0,0 +1,47 @@ +/* + * "THE CHEESE-WARE LICENSE" (Revision 1): + * wrote this file. As long as you retain this notice + * you can do whatever you want with this stuff. If we meet some day, + * and you think this stuff is worth it, you can buy me some cheese + * in return + */ + +#include +#include +#include + +#include "common.h" + +#define PROG_PREFIX "son: " +#define log(fmt, args...) printf(PROG_PREFIX fmt "\n", ##args) + +int main(int argc, const char **argv) +{ + log("\n" + "HEEEEEY, father\n" + "There's an endless road to rediscover\n" + "HEEEEEY, sister\n" + "Do you still belive in love I wonder"); + if (argc != 2) { + log("Ooops, wrong amount of args, %d", argc); + return EXIT_FAILURE; + } + long mode = strtol(argv[1], NULL, 10); + log("mode: %ld", mode); + switch(mode) { + case WAIT_FOR_CHILD: + log("pid %d ppid %d", getpid(), getppid()); + sleep(5); + break; + case DONT_WAIT_FOR_CHILD: + log("before parent die: pid %d ppid %d", getpid(), getppid()); + sleep(5); + log("after parent die: pid %d ppid %d", getpid(), getppid()); + break; + case ZOMBIE_PROCESS: + break; + default: + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/OSs/lab2/unix/part-B/Makefile b/OSs/lab2/unix/part-B/Makefile new file mode 100644 index 0000000..da8fa15 --- /dev/null +++ b/OSs/lab2/unix/part-B/Makefile @@ -0,0 +1,12 @@ +targets = main +all: $(targets) + +main: main.o + $(CC) -o $@ $^ $(CFLAGS) + +%.o: %.c + $(CC) -c $^ -o $@ $(CFLAGS) + +clean: + rm -f $(targets) + rm -f *.o diff --git a/OSs/lab2/unix/part-B/README.txt b/OSs/lab2/unix/part-B/README.txt new file mode 100644 index 0000000..259541c --- /dev/null +++ b/OSs/lab2/unix/part-B/README.txt @@ -0,0 +1 @@ +Чтобы показать эту лабу просто соберите ее через make и запустите получившийся исполняемый файл diff --git a/OSs/lab2/unix/part-B/main.c b/OSs/lab2/unix/part-B/main.c new file mode 100644 index 0000000..38fefef --- /dev/null +++ b/OSs/lab2/unix/part-B/main.c @@ -0,0 +1,53 @@ +/* + * "THE CHEESE-WARE LICENSE" (Revision 1): + * wrote this file. As long as you retain this notice + * you can do whatever you want with this stuff. If we meet some day, + * and you think this stuff is worth it, you can buy me some cheese + * in return + */ + +#include +#include +#include +#include +#include + +volatile unsigned long long global = 0; + +#define NR_THREADS 4 +#define GLOBAL_STOP_VALUE 15 + +pthread_t threads[NR_THREADS] = {0}; + +void *thread_routine(void* args) +{ + size_t arg = *((size_t *) args); + // Так как на глобальном счетчике нет синхронизации, + // количество выводов в консоль можен не совпадать с + // GLOBAL_STOP_VALUE + while (global < GLOBAL_STOP_VALUE) { + printf("Hello from thread %lu\n", arg); + global += 1; + sleep(5); + } + pthread_exit(NULL); +} + +int main() +{ + for (size_t i = 0; i < NR_THREADS; i++) { + size_t *arg = malloc(sizeof(*arg)); + assert(arg); + *arg = i; + pthread_create(&threads[i], NULL, thread_routine, arg); + } + + int ret; + for (size_t i = 0; i < NR_THREADS; i++) { + ret = pthread_join(threads[i], NULL); + if (ret) { + break; + } + } + return 0; +}