Add processes algorithms

This commit is contained in:
Francesco Di Stasio 2024-08-07 23:43:52 +02:00
parent e5dad3fa8d
commit 4eabd56405
8 changed files with 528 additions and 0 deletions

67
processes/dup2.c Normal file
View File

@ -0,0 +1,67 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include "macros.h"
#define BUFFER_SIZE 1024
// fork(), pipe(), dup2(), execlp()
int main() {
int retvalue, pipe_fd[2];
// Create pipe
SYSC(retvalue, pipe(pipe_fd), "pipe error");
// Create Child Process
pid_t pid;
SYSC(pid, fork(), "fork error");
if (pid == 0) {
// Child Process
// Close pipe file descriptor (read)
SYSC(retvalue, close(pipe_fd[0]), "close error");
// stdout redirection in pipe's write file descriptor
SYSC(retvalue, dup2(pipe_fd[1], STDOUT_FILENO), "dup2 error");
// Close pipe file descriptor (write)
SYSC(retvalue, close(pipe_fd[1]), "close error");
// Exec "ls -la"
execlp("ls", "ls -la", (char *) NULL);
// Exec error
perror("execlp");
exit(EXIT_FAILURE);
} else {
// Father Process
char buffer[BUFFER_SIZE];
// Close pipe file descriptor (write)
SYSC(retvalue, close(pipe_fd[1]), "close error");
// Read from pipe
ssize_t n_read;
SYSC(n_read, read(pipe_fd[0], buffer, BUFFER_SIZE), "read error");
// Write on pipe
SYSC(retvalue, write(STDOUT_FILENO, buffer, n_read), "write error");
// Close pipe file descriptor (read)
SYSC(retvalue, close(pipe_fd[0]), "close error");
// Wait child process
SYSC(retvalue, waitpid(pid, NULL, 0), "waitpid error");
}
return 0;
}

74
processes/dup2_pipe.c Normal file
View File

@ -0,0 +1,74 @@
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "macros.h"
#include "constants.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
// fork(), pipe(), dup2(), execlp()
int main(int argc, char* argv[]){
pid_t pid_ls, pid_wc;
int pfd[2], ret_value;
// Create Pipe
SYSC(ret_value, pipe(pfd), "Pipe error");
// Create Child Process (will exec ls -l)
SYSC(pid_ls, fork(), "fork error");
if (pid_ls == 0) {
// Child Process
// stdout redirection in pipe's write file descriptor
SYSC(ret_value, dup2(pfd[1], fileno(stdout)), "dup2 error");
// Close pipe file descriptors (read and write)
SYSC(ret_value, close(pfd[1]), "close pipe error");
SYSC(ret_value, close(pfd[0]), "close pipe error");
// Exec "ls -l"
execlp("ls", "ls", "-l", NULL);
// Exec error
perror("exec");
exit(EXIT_FAILURE);
}
// Create Child Process (will exec wc -l)
SYSC(pid_wc, fork(), "fork error");
if (pid_wc == 0) {
// Child Process
// stdin redirection in pipe's read file descriptor
SYSC(ret_value, dup2(pfd[0], fileno(stdin)), "dup2 error");
// Close pipe file descriptors (read and write)
SYSC(ret_value, close(pfd[0]), "close pipe error");
SYSC(ret_value, close(pfd[1]), "close pipe error");
// Exec "wc -l"
execlp("wc", "wc", "-l", NULL);
// Exec error
perror("exec");
exit(EXIT_FAILURE);
}
// Close pipe file descriptors (read and write)
SYSC(ret_value, close(pfd[1]), "close pipe error");
SYSC(ret_value, close(pfd[0]), "close pipe error");
// Wait Child processes
SYSC(ret_value, waitpid(pid_ls, NULL, 0), "waitpid error");
SYSC(ret_value, waitpid(pid_wc, NULL, 0), "waitpid error");
}

45
processes/exec.c Normal file
View File

@ -0,0 +1,45 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include "macros.h"
// fork(), exec(), waitpid()
int main() {
pid_t pid;
int retvalue;
SYSC(pid, fork(), "fork error");
if (pid == 0) {
// Child Process
// Exec ls -l
char *args[] = {"ls", "-l", NULL};
execvp("ls", args);
// Exec error
perror("exec");
return 1;
} else {
// Father Process
// Wait Child Process
int status;
pid_t child_pid;
SYSC(child_pid, waitpid(pid, &status, 0), "waitpid error");
if (WIFEXITED(status)) {
printf("Child process exited with code: %d\n", WEXITSTATUS(status));
} else {
printf("Child process exit error \n");
}
}
return 0;
}

47
processes/fork.c Normal file
View File

@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include "macros.h"
// fork(), wait()
int main() {
pid_t pid;
// Create Child process
SYSC(pid, fork(), "fork error");
if (pid == 0) {
// Child process
printf("I'm the Child process, PID: %d\n", getpid());
// Exit from child process
exit(EXIT_SUCCESS);
} else {
// Father Process
printf("I'm the Father process, PID: %d\n", getpid());
// Wait Child Process
int status;
pid_t child_pid;
SYSC(child_pid, wait(&status), "wait error");
if (WIFEXITED(status)) {
printf("Child process exited with code: %d\n", WEXITSTATUS(status));
} else {
printf("Child process exit error \n");
}
// Exit from father process
exit(EXIT_SUCCESS);
}
}

2
processes/macros.h Normal file
View File

@ -0,0 +1,2 @@
#define SYSC(value,command,message) if ((value = command) == -1){perror(message); exit(errno); }
#define SYSCN(value,command,message) if ((value = command) == NULL){perror(message); exit(errno); }

66
processes/pipe.c Normal file
View File

@ -0,0 +1,66 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "macros.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUFFER_SIZE 1024
// fork(), pipe()
int main() {
int pipe_fd[2], retvalue;
pid_t pid;
char buffer[BUFFER_SIZE];
// Create Pipe
SYSC(retvalue, pipe(pipe_fd), "pipe error");
// Create child process
SYSC(pid, fork(), "fork error");
if (pid == 0) {
// Child Process
// Close pipe file descriptor (write)
SYSC(retvalue, close(pipe_fd[1]), "close error");
// Read from pipe
ssize_t n_read, n_written;
SYSC(n_read, read(pipe_fd[0], buffer, BUFFER_SIZE), "read error");
// Write on pipe
SYSC(n_written, write(STDOUT_FILENO, buffer, n_read), "write error");
// Close pipe file descriptor (read)
SYSC(retvalue, close(pipe_fd[0]), "close error");
exit(EXIT_SUCCESS);
} else {
// Father Process
// Close pipe file descriptor (read)
SYSC(retvalue, close(pipe_fd[0]), "close error");
// Write on pipe
ssize_t n_written;
const char *data_to_send = "Hello child process!";
SYSC(n_written, write(pipe_fd[1], data_to_send, strlen(data_to_send)), "write error");
// Close pipe file descriptor (write)
SYSC(retvalue, close(pipe_fd[1]), "nella close");
pid_t pid_c;
// Wait child process
SYSC(pid_c, waitpid(pid, NULL, 0), "nella waitpid");
}
return 0;
}

158
processes/semaphores.c Normal file
View File

@ -0,0 +1,158 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <sys/wait.h>
#include <errno.h>
#include "macros.h"
#define BUFFER_SIZE 10
#define SHARED_MEM_NAME "/shared_memory"
#define SEM_MUTEX_NAME "/sem_mutex"
#define SEM_EMPTY_NAME "/sem_empty"
#define SEM_FULL_NAME "/sem_full"
typedef struct {
char buffer[BUFFER_SIZE];
int read_index;
int write_index;
} SharedData;
void writer(sem_t*, sem_t*, sem_t*, SharedData*);
void reader(sem_t*, sem_t*, sem_t*, SharedData*);
int main() {
int shm_fd,retvalue;
sem_t *sem_mutex, *sem_empty, *sem_full;
SharedData *shared_data;
// Create shared memory segment
SYSC(shm_fd, shm_open(SHARED_MEM_NAME, O_CREAT | O_RDWR, 0666), "shm_open error");
SYSC(retvalue, ftruncate(shm_fd, sizeof(SharedData)), "ftruncate error");
// Shared memory mapping
SYSCN(shared_data, (SharedData *)mmap(NULL, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0), "mmap error");
// Create semaphores
SYSCN(sem_mutex, sem_open(SEM_MUTEX_NAME, O_CREAT | O_EXCL, 0666, 1), "sem_mutex: open");
SYSCN(sem_empty, sem_open(SEM_EMPTY_NAME, O_CREAT | O_EXCL, 0666, 0), "sem_empty: open");
SYSCN(sem_full, sem_open(SEM_FULL_NAME, O_CREAT | O_EXCL, 0666, BUFFER_SIZE), "sem_full: open");
// Circular buffer init
shared_data->read_index = 0;
shared_data->write_index = 0;
// Create Child process
SYSC(retvalue, fork(), "fork error");
if (!retvalue) {
// Child Process (reader)
reader(sem_mutex, sem_empty, sem_full, shared_data);
} else {
// Father Process
// Create Child process
SYSC(retvalue, fork(), "fork error");
if (!retvalue) {
// Child Process (writer)
writer(sem_mutex, sem_empty, sem_full, shared_data);
}
}
// Wait Child processes
SYSC(retvalue, wait(NULL), "wait error");
// Close resources
SYSC(retvalue, munmap(shared_data, sizeof(SharedData)), "munmap error");
SYSC(retvalue, close(shm_fd), "close error");
SYSC(retvalue, sem_close(sem_mutex), "sem_close error");
SYSC(retvalue, sem_close(sem_empty), "sem_close error");
SYSC(retvalue, sem_close(sem_full), "sem_close error");
SYSC(retvalue, sem_unlink(SEM_MUTEX_NAME), "sem_unlink error");
SYSC(retvalue, sem_unlink(SEM_EMPTY_NAME), "sem_unlink error");
SYSC(retvalue, sem_unlink(SEM_FULL_NAME), "sem_unlink error");
SYSC(retvalue, shm_unlink(SHARED_MEM_NAME), "shm_unlink error");
return 0;
}
void reader(sem_t *sem_mutex, sem_t *sem_empty, sem_t *sem_full, SharedData *shared_data) {
char data;
int retvalue;
while (1) {
// Wait data
SYSC(retvalue, sem_wait(sem_empty), "sem_wait error");
// Mutex lock
SYSC(retvalue, sem_wait(sem_mutex), "sem_wait error");
// Read from buffer
data = shared_data->buffer[shared_data->read_index];
shared_data->read_index = (shared_data->read_index + 1) % BUFFER_SIZE;
// Mutex unlock
SYSC(retvalue, sem_post(sem_mutex), "sem_post error");
// Increment data on buffer full counter
SYSC(retvalue, sem_post(sem_full), "sem_post error");
// Write read data on stdout
printf("Reader - Read: %c\n", data);
if(data == 'Z') exit(EXIT_SUCCESS);
// Simulate elaboration time
usleep(100000);
}
}
void writer(sem_t *sem_mutex, sem_t *sem_empty, sem_t *sem_full, SharedData *shared_data) {
char data = 'A';
int retvalue;
while (1) {
// Wait free slots
SYSC(retvalue, sem_wait(sem_full), "sem_wait error");
// Mutex lock
SYSC(retvalue, sem_wait(sem_mutex), "sem_wait error");
// Write on buffer
shared_data->buffer[shared_data->write_index] = data;
shared_data->write_index = (shared_data->write_index + 1) % BUFFER_SIZE;
// Mutex unlock
SYSC(retvalue, sem_post(sem_mutex), "sem_post error");
// Increment data on buffer empty counter
SYSC(retvalue, sem_post(sem_empty), "sem_post error");
// Write wrote data on stdout
printf("Writer - Wrote: %c\n", data);
// Change char
if(data == 'Z') exit(EXIT_SUCCESS);
data = data + 1;
// Simulate elaboration time
usleep(150000);
}
}

69
processes/shared_memory.c Normal file
View File

@ -0,0 +1,69 @@
#include <sys/wait.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include "macros.h"
#define MEM_SIZE 4096
// fork(), shm_open(), mmap()
int main (int argc, char *ARGV[]) {
// Param check
if(argc != 2) {
fprintf(stderr, "Usage: %s <shm_name>\n", ARGV[0]);
exit(EXIT_FAILURE);
}
int retvalue, mem_fd;
// Create shared memory segment
SYSC(mem_fd, shm_open(ARGV[1], O_CREAT | O_RDWR, 0666), "shm_open error");
SYSC(retvalue, ftruncate(mem_fd, MEM_SIZE), "ftruncate error");
// Create Child Process
pid_t pid;
SYSC(pid, fork(), "fork error");
if (pid == 0) {
// Child Process
// Shared memory mapping
void *ptr;
SYSCN(ptr, mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, 0), "mmap error");
// Write on shared memory segment
const char *msg = "Hello, shared memory!\n";
SYSC(retvalue, sprintf(ptr, "%s", msg), "sprintf error");
// Shared memory unmapping
SYSC(retvalue, munmap(ptr, MEM_SIZE), "munmap error");
exit(EXIT_SUCCESS);
} else {
// Father Process
// Shared memory mapping
void *ptr;
SYSCN(ptr, mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, 0), "mmap error");
// Wait Child process
SYSC(retvalue, waitpid(pid, NULL, 0), "waitpid error");
// Write read data on stdout
SYSC(retvalue, write(STDOUT_FILENO, ptr, strlen(ptr)), "write error");
// Shared memory unmapping
SYSC(retvalue, munmap(ptr, MEM_SIZE), "munmap error");
exit(EXIT_SUCCESS);
}
}