mirror of
https://github.com/TheAlgorithms/C
synced 2024-11-25 06:49:36 +03:00
Add processes algorithms
This commit is contained in:
parent
e5dad3fa8d
commit
4eabd56405
67
processes/dup2.c
Normal file
67
processes/dup2.c
Normal 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
74
processes/dup2_pipe.c
Normal 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
45
processes/exec.c
Normal 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
47
processes/fork.c
Normal 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
2
processes/macros.h
Normal 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
66
processes/pipe.c
Normal 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
158
processes/semaphores.c
Normal 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
69
processes/shared_memory.c
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user