First implementation of lab1
This commit is contained in:
parent
2e968232c2
commit
f8286f50b0
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,5 @@
|
|||||||
/.idea/
|
/.idea/
|
||||||
/*build*/
|
*build*/
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
*.obj
|
||||||
*.exe
|
*.exe
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
services:
|
services:
|
||||||
environment:
|
environment:
|
||||||
image: "bgtu/os/environment:l1v0.3"
|
image: "bgtu/os/environment:l1v1"
|
||||||
build:
|
build:
|
||||||
dockerfile: ./environment.dockerfile
|
dockerfile: ./environment.dockerfile
|
@ -1,6 +1,3 @@
|
|||||||
FROM alpine:3.20.3
|
FROM alpine:3.20.3
|
||||||
RUN apk update && apk upgrade
|
RUN apk update && apk upgrade
|
||||||
RUN apk add clang cmake linux-headers
|
RUN apk add clang cmake linux-headers lldb make gdb
|
||||||
RUN apk add lldb
|
|
||||||
RUN apk add make
|
|
||||||
RUN apk add gdb
|
|
7
lab1/v7/CMakeLists.txt
Normal file
7
lab1/v7/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
project(os)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
add_executable(using_pause using_pause.c)
|
||||||
|
add_executable(using_signal_handlers using_signal_handlers.c)
|
56
lab1/v7/using_pause.c
Normal file
56
lab1/v7/using_pause.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
void wait_clocks(clock_t clocks_to_wait) {
|
||||||
|
const clock_t end = clock() + clocks_to_wait;
|
||||||
|
while (clock() < end);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ping_pong_data {
|
||||||
|
char const *name;
|
||||||
|
const pid_t pid_to_print;
|
||||||
|
const pid_t pid_to_send;
|
||||||
|
double delay_seconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
int run_exchange(char const *name, pid_t pid_to_print, pid_t pid_to_send, int wait_first, double delay_seconds) {
|
||||||
|
const clock_t delay_clocks = (clock_t) (CLOCKS_PER_SEC * delay_seconds);
|
||||||
|
if (wait_first)
|
||||||
|
goto WAIT;
|
||||||
|
while (1) {
|
||||||
|
printf("[%s] Got signal\n", name);
|
||||||
|
printf("[%s] PID=%d\n", name, pid_to_print);
|
||||||
|
printf("[%s] Sleeping %lf seconds before sending signal\n", name, delay_seconds);
|
||||||
|
wait_clocks(delay_clocks);
|
||||||
|
printf("[%s] Sending signal\n", name);
|
||||||
|
kill(pid_to_send, SIGUSR1);
|
||||||
|
WAIT:
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
perror("Program interrupted");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void noop(int){
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
signal(SIGUSR1, noop);
|
||||||
|
pid_t parent_pid = getpid();
|
||||||
|
pid_t child_pid = fork();
|
||||||
|
|
||||||
|
switch (child_pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Failed to fork\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
case 0:
|
||||||
|
child_pid = getpid();
|
||||||
|
return run_exchange("c", parent_pid, parent_pid, 1, 2.5);
|
||||||
|
default:
|
||||||
|
return run_exchange("p", child_pid, child_pid, 0, 2.5);
|
||||||
|
}
|
||||||
|
}
|
45
lab1/v7/using_pipes.c
Normal file
45
lab1/v7/using_pipes.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int run_exchange(int in_pipe, int out_pipe) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct {
|
||||||
|
int in_pipe;
|
||||||
|
int out_pipe;
|
||||||
|
} p2c_pipe, c2p_pipe;
|
||||||
|
|
||||||
|
if (pipe2((int *) &p2c_pipe, O_DIRECT) == -1) {
|
||||||
|
perror("Failed to create pipes\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (pipe2((int *) &c2p_pipe, O_DIRECT) == -1) {
|
||||||
|
close(p2c_pipe.in_pipe);
|
||||||
|
close(p2c_pipe.out_pipe);
|
||||||
|
perror("Failed to create pipes\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t parent_pid = getpid();
|
||||||
|
pid_t child_pid = fork();
|
||||||
|
|
||||||
|
switch (child_pid) {
|
||||||
|
case -1:
|
||||||
|
close(p2c_pipe.in_pipe);
|
||||||
|
close(p2c_pipe.out_pipe);
|
||||||
|
close(c2p_pipe.in_pipe);
|
||||||
|
close(c2p_pipe.out_pipe);
|
||||||
|
perror("Failed to fork\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
case 0:
|
||||||
|
close(p2c_pipe.in_pipe);
|
||||||
|
close(c2p_pipe.out_pipe);
|
||||||
|
default:
|
||||||
|
close(c2p_pipe.in_pipe);
|
||||||
|
close(p2c_pipe.out_pipe);
|
||||||
|
}
|
||||||
|
}
|
83
lab1/v7/using_signal_handlers.c
Normal file
83
lab1/v7/using_signal_handlers.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
void wait_clocks(clock_t clocks_to_wait) {
|
||||||
|
const clock_t end = clock() + clocks_to_wait;
|
||||||
|
while (clock() < end);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ping_pong_data_t {
|
||||||
|
char const *name;
|
||||||
|
pid_t pid_to_print;
|
||||||
|
pid_t pid_to_send;
|
||||||
|
double delay_seconds;
|
||||||
|
} ping_pong_data;
|
||||||
|
|
||||||
|
|
||||||
|
void do_ping_pong(int signo) {
|
||||||
|
if (signo != SIGUSR1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const clock_t delay_clocks = (clock_t) (CLOCKS_PER_SEC * ping_pong_data.delay_seconds);
|
||||||
|
|
||||||
|
printf("[%s] Got signal\n", ping_pong_data.name);
|
||||||
|
printf("[%s] PID=%d\n", ping_pong_data.name, ping_pong_data.pid_to_print);
|
||||||
|
printf("[%s] Sleeping %lf seconds before sending signal\n", ping_pong_data.name, ping_pong_data.delay_seconds);
|
||||||
|
wait_clocks(delay_clocks);
|
||||||
|
printf("[%s] Sending signal\n", ping_pong_data.name);
|
||||||
|
kill(ping_pong_data.pid_to_send, SIGUSR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile int is_running = 1;
|
||||||
|
|
||||||
|
void interrupt(int signo) {
|
||||||
|
if (signo != SIGINT)
|
||||||
|
return;
|
||||||
|
is_running = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
signal(SIGINT, interrupt);
|
||||||
|
|
||||||
|
pid_t parent_pid = getpid();
|
||||||
|
pid_t child_pid = fork();
|
||||||
|
|
||||||
|
|
||||||
|
switch (child_pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Failed to fork\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
case 0:
|
||||||
|
child_pid = getpid();
|
||||||
|
|
||||||
|
ping_pong_data.name = "c";
|
||||||
|
ping_pong_data.delay_seconds = 2.5;
|
||||||
|
ping_pong_data.pid_to_print = parent_pid;
|
||||||
|
ping_pong_data.pid_to_send = parent_pid;
|
||||||
|
|
||||||
|
signal(SIGUSR1, do_ping_pong);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ping_pong_data.name = "c";
|
||||||
|
ping_pong_data.delay_seconds = 2.5;
|
||||||
|
ping_pong_data.pid_to_print = child_pid;
|
||||||
|
ping_pong_data.pid_to_send = child_pid;
|
||||||
|
|
||||||
|
signal(SIGUSR1, do_ping_pong);
|
||||||
|
|
||||||
|
kill(parent_pid, SIGUSR1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (is_running)
|
||||||
|
pause();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user