stuff
This commit is contained in:
BIN
Examples/a.out
BIN
Examples/a.out
Binary file not shown.
13
Examples/ipc/Makefile
Normal file
13
Examples/ipc/Makefile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CC=gcc
|
||||||
|
CFLAGS=-Wall -Wextra -g
|
||||||
|
LFLAGS=-lrt
|
||||||
|
|
||||||
|
BINS=$(patsubst %.c,%,$(wildcard *.c))
|
||||||
|
|
||||||
|
all: $(BINS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BINS) MYFILE
|
||||||
|
|
||||||
|
%: %.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ $< $(LFLAGS)
|
||||||
35
Examples/ipc/README.md
Normal file
35
Examples/ipc/README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Inter-process communication (IPC) examples
|
||||||
|
|
||||||
|
CS3841 examples using IPC mechanisms to communicate between processes
|
||||||
|
|
||||||
|
* ipcfs1.c - Using the file system for inter-process communication
|
||||||
|
Shows a problem with the fact that the file position pointer is shared between parent and childUsing fork to create two processes
|
||||||
|
|
||||||
|
* ipcfs2.c - Using the file system for inter-process communication
|
||||||
|
Fixes the file position pointer problem in ipcfs1.c by using lseek to reset the pointer to the beginning
|
||||||
|
Shows the frustration with using the file system for IPC by needing to move the file position pointer around
|
||||||
|
|
||||||
|
* ipcpipe1.c - Using a pipe to communicate data from a child process to a parent process
|
||||||
|
|
||||||
|
* ipcpipe2.c - Pipes are unidirectional and require two pipes to send data in two directions
|
||||||
|
|
||||||
|
* ipcmsg1.c - Using a message queue to send data from a parent process to a child process
|
||||||
|
NOTE: message queues are persistent
|
||||||
|
|
||||||
|
* ipcmsg2.c - ses message queues to send multiple messages between two processes
|
||||||
|
Shows what can happen with blocking queues when the queue gets full
|
||||||
|
NOTE: message queues are persistent
|
||||||
|
|
||||||
|
* signal1.c - Shows how to set up a signal handler for the interrupt (CTRL+C) signal
|
||||||
|
|
||||||
|
* signal2.c - Shows how to set up a signal handler for the segmentation fault signal
|
||||||
|
Unfortunately does not fix the segmentation fault and essentially loops forever
|
||||||
|
|
||||||
|
* ipcsignal.c - Shows how to use the kill system call to send a signal from one process to another
|
||||||
|
|
||||||
|
* ipcshm1.c - Uses shared memory to send data from a child process to a parent process
|
||||||
|
NOTE: named shared memory segments are persistent
|
||||||
|
|
||||||
|
* ipcshm2.c - Uses shared memory to send data from a child process to a parent process
|
||||||
|
Uses shm\_unlink to remove the shared memory when done
|
||||||
|
NOTE: named shared memory segments are persistent
|
||||||
54
Examples/ipc/ipcfs1.c
Normal file
54
Examples/ipc/ipcfs1.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* ipcsfs1 - Using the file system for inter-process communication
|
||||||
|
* Shows a problem with the fact that the file position
|
||||||
|
* pointer is shared between parent and child
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h> // needed for open system call
|
||||||
|
#include <stdio.h> // needed for printf
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <string.h> // nneded for strlen
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <unistd.h> // needed for fork, read, write, close system calls
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Open a file for reading and writing
|
||||||
|
// Create it if it doesn't exist
|
||||||
|
int myfile = open("MYFILE", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if (pid < 0) // error
|
||||||
|
{
|
||||||
|
printf("ERROR: COULD NOT FORK\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if (pid == 0) // child
|
||||||
|
{
|
||||||
|
/* Write to parent */
|
||||||
|
char *data = "HELLO";
|
||||||
|
write(myfile, data, strlen(data));
|
||||||
|
printf("Child wrote %s\n", data);
|
||||||
|
|
||||||
|
/* Close file */
|
||||||
|
close(myfile);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
/* Wait for child */
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
/* Read data */
|
||||||
|
char data[32];
|
||||||
|
read(myfile, data, sizeof(data));
|
||||||
|
printf("Parent received %s from child\n", data);
|
||||||
|
|
||||||
|
/* Close file */
|
||||||
|
close(myfile);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
59
Examples/ipc/ipcfs2.c
Normal file
59
Examples/ipc/ipcfs2.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* ipcsfs2 - Using the file system for inter-process communication
|
||||||
|
* Fixes the file position pointer problem in ipcfs1.c
|
||||||
|
* by using lseek to reset the pointer to the beginning
|
||||||
|
* Shows the frustration with using the file system for
|
||||||
|
* IPC by needing to move the file position pointer around
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h> // needed for open system call
|
||||||
|
#include <stdio.h> // needed for printf
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <string.h> // nneded for strlen
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <unistd.h> // needed for fork, read, write, close system calls
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Open a file for reading and writing
|
||||||
|
// Create it if it doesn't exist
|
||||||
|
int myfile = open("MYFILE", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if (pid < 0) // error
|
||||||
|
{
|
||||||
|
printf("ERROR: COULD NOT FORK\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if (pid == 0) // child
|
||||||
|
{
|
||||||
|
/* Write to parent */
|
||||||
|
char *data = "HELLO";
|
||||||
|
write(myfile, data, strlen(data));
|
||||||
|
printf("Child wrote %s\n", data);
|
||||||
|
|
||||||
|
/* Close file */
|
||||||
|
close(myfile);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
/* Wait for child */
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
/* Reset file position pointer */
|
||||||
|
lseek(myfile, 0, SEEK_SET);
|
||||||
|
|
||||||
|
/* Read data */
|
||||||
|
char data[32];
|
||||||
|
read(myfile, data, sizeof(data));
|
||||||
|
printf("Parent received %s from child\n", data);
|
||||||
|
|
||||||
|
/* Close file */
|
||||||
|
close(myfile);
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
71
Examples/ipc/ipcmsg1.c
Normal file
71
Examples/ipc/ipcmsg1.c
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* ipcmsg1.c - Using a message queue to send data from
|
||||||
|
* a parent process to a child process
|
||||||
|
* NOTE: message queues are persistent
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <unistd.h> // needed for fork system call
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <stdio.h> // needed for printf, perror
|
||||||
|
#include <mqueue.h> // needed for mq system calls
|
||||||
|
#include <string.h> // needed for strcpy
|
||||||
|
|
||||||
|
/* Struct for the queue message */
|
||||||
|
typedef struct message {
|
||||||
|
int message_id;
|
||||||
|
char string[10];
|
||||||
|
} message;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Create attributes for new queue
|
||||||
|
struct mq_attr queue_attr;
|
||||||
|
queue_attr.mq_flags = 0; // Ignored by kernel
|
||||||
|
queue_attr.mq_maxmsg = 10; // Max messages the queue supports
|
||||||
|
queue_attr.mq_msgsize = sizeof(message);
|
||||||
|
queue_attr.mq_curmsgs = 0; // Not used
|
||||||
|
|
||||||
|
// Create and open a queue
|
||||||
|
mqd_t mqdes = mq_open("/CS3841QUEUE", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &queue_attr);
|
||||||
|
if(mqdes == -1) {
|
||||||
|
printf("COULD NOT OPEN QUEUE\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if(pid < 0) // error
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if(pid == 0) // child
|
||||||
|
{
|
||||||
|
// Child receives message from parent
|
||||||
|
message from_parent;
|
||||||
|
mq_receive(mqdes, (char*)&from_parent, sizeof(message), NULL);
|
||||||
|
printf("Child got %d: %s from parent\n", from_parent.message_id, from_parent.string);
|
||||||
|
|
||||||
|
// Close the queue
|
||||||
|
mq_close(mqdes);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
// Parent sends message to child
|
||||||
|
message to_child;
|
||||||
|
to_child.message_id = 10;
|
||||||
|
strcpy(to_child.string, "HELLO");
|
||||||
|
mq_send(mqdes, (char*)&to_child, sizeof(message), 0);
|
||||||
|
|
||||||
|
// Wait for child
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
// Close the queue
|
||||||
|
mq_close(mqdes);
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
74
Examples/ipc/ipcmsg2.c
Normal file
74
Examples/ipc/ipcmsg2.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* ipcmsg2.c - Uses message queues to send multiple messages
|
||||||
|
* between two processes. Shows what can happen
|
||||||
|
* with blocking queues when the queue gets full
|
||||||
|
* NOTE: message queues are persistent
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <unistd.h> // needed for fork system call
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <stdio.h> // needed for printf, perror
|
||||||
|
#include <mqueue.h> // needed for mq system calls
|
||||||
|
#include <string.h> // needed for strcpy
|
||||||
|
|
||||||
|
/* Struct for the queue message */
|
||||||
|
typedef struct message {
|
||||||
|
int message_id;
|
||||||
|
char string[10];
|
||||||
|
} message;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Create attributes for new queue
|
||||||
|
struct mq_attr queue_attr;
|
||||||
|
queue_attr.mq_flags = 0; // Ignored by kernel
|
||||||
|
queue_attr.mq_maxmsg = 10; // Max messages the queue supports
|
||||||
|
queue_attr.mq_msgsize = sizeof(message);
|
||||||
|
queue_attr.mq_curmsgs = 0; // Not used
|
||||||
|
|
||||||
|
// Create and open a queue
|
||||||
|
mqd_t mqdes = mq_open("/CS3841QUEUE", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &queue_attr);
|
||||||
|
if(mqdes == -1) {
|
||||||
|
printf("COULD NOT OPEN QUEUE\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if(pid < 0) // error
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if(pid == 0) // child
|
||||||
|
{
|
||||||
|
// Child receives message from parent
|
||||||
|
message from_parent;
|
||||||
|
mq_receive(mqdes, (char*)&from_parent, sizeof(message), NULL);
|
||||||
|
printf("Child got %d: %s from parent\n", from_parent.message_id, from_parent.string);
|
||||||
|
|
||||||
|
// Close the queue
|
||||||
|
mq_close(mqdes);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
// Parent sends messages to child
|
||||||
|
message to_child;
|
||||||
|
for(int i = 0; i < 10; i++) {
|
||||||
|
to_child.message_id = i;
|
||||||
|
strcpy(to_child.string, "HELLO");
|
||||||
|
mq_send(mqdes, (char*)&to_child, sizeof(message), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for child
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
// Close the queue
|
||||||
|
mq_close(mqdes);
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
58
Examples/ipc/ipcpipe1.c
Normal file
58
Examples/ipc/ipcpipe1.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* ipcpipe1.c - Using a pipe to communicate data from
|
||||||
|
* a child process to a parent process
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <unistd.h> // needed for fork, read, write, close system calls
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <stdio.h> // needed for printf, perror
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
/* Create a pipe */
|
||||||
|
int pipefd[2];
|
||||||
|
if (pipe(pipefd) == -1) {
|
||||||
|
perror("pipe");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if (pid == -1) // error
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if (pid == 0) // child
|
||||||
|
{
|
||||||
|
/* Close unused write end */
|
||||||
|
close(pipefd[1]);
|
||||||
|
|
||||||
|
/* Read from parent */
|
||||||
|
char data[32];
|
||||||
|
read(pipefd[0], data, sizeof(data));
|
||||||
|
printf("Child received %s from parent\n", data);
|
||||||
|
|
||||||
|
/* Close pipe */
|
||||||
|
close(pipefd[0]);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
/* Close unused read end */
|
||||||
|
close(pipefd[0]);
|
||||||
|
|
||||||
|
/* Write to child */
|
||||||
|
write(pipefd[1], "HELLO", 5);
|
||||||
|
|
||||||
|
/* Close pipe */
|
||||||
|
close(pipefd[1]);
|
||||||
|
|
||||||
|
/* Wait or child */
|
||||||
|
wait(0);
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
75
Examples/ipc/ipcpipe2.c
Normal file
75
Examples/ipc/ipcpipe2.c
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* ipcpipe2.c - Pipes are unidirectional and require
|
||||||
|
* two pipes to send data in two directions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <unistd.h> // needed for fork, read, write, close system calls
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <stdio.h> // needed for printf, perror
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
/* Create pipes */
|
||||||
|
int pipe_to_child[2];
|
||||||
|
if (pipe(pipe_to_child) == -1) {
|
||||||
|
printf("PIPE FAILURE\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
int pipe_from_child[2];
|
||||||
|
if (pipe(pipe_from_child) == -1) {
|
||||||
|
printf("PIPE FAILURE\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if (pid == -1) // error
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if (pid == 0) //
|
||||||
|
{
|
||||||
|
/* Close unused pipe ends */
|
||||||
|
close(pipe_to_child[1]);
|
||||||
|
close(pipe_from_child[0]);
|
||||||
|
|
||||||
|
/* Write to parent */
|
||||||
|
write(pipe_from_child[1], "CHELLO", 6);
|
||||||
|
close(pipe_from_child[1]);
|
||||||
|
|
||||||
|
/* Read from parent */
|
||||||
|
char data[32];
|
||||||
|
read(pipe_to_child[0], data, sizeof(data));
|
||||||
|
printf("Child received %s from parent\n", data);
|
||||||
|
|
||||||
|
/* Close pipe */
|
||||||
|
close(pipe_to_child[0]);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
/* Close unused pipe ends */
|
||||||
|
close(pipe_to_child[0]);
|
||||||
|
close(pipe_from_child[1]);
|
||||||
|
|
||||||
|
/* Write to child */
|
||||||
|
write(pipe_to_child[1], "PHELLO", 6);
|
||||||
|
close(pipe_to_child[1]);
|
||||||
|
|
||||||
|
/* Read from child */
|
||||||
|
char data[32];
|
||||||
|
read(pipe_from_child[0], data, sizeof(data));
|
||||||
|
printf("Parent recieved %s from child\n", data);
|
||||||
|
|
||||||
|
/* Close pipe */
|
||||||
|
close(pipe_from_child[0]);
|
||||||
|
|
||||||
|
/* Wait for child */
|
||||||
|
wait(0);
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
74
Examples/ipc/ipcshm1.c
Normal file
74
Examples/ipc/ipcshm1.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* ipcshm1.c - Uses shared memory to send data from
|
||||||
|
* a child process to a parent process
|
||||||
|
* NOTE: named shared memory segments are persistent
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <fcntl.h> // needed for parameter values for shm_open
|
||||||
|
#include <unistd.h> // needed for fork, getpid, getppid, kill system calls
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <signal.h> // needed for signal system call
|
||||||
|
#include <stdio.h> // needed for printf, perror
|
||||||
|
#include <sys/mman.h> // needed for mmap, munmap, shm system calls
|
||||||
|
#include <string.h> // needed for strcpy
|
||||||
|
|
||||||
|
#define MAPPED_SIZE 128
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Create and open a shared memory segment
|
||||||
|
int shmfd = shm_open("/CS3841MEMORY", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
|
if(shmfd == -1) {
|
||||||
|
printf("COULD NOT OPEN SHARED MEMORY SEGMENT\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the size of the shared memory segment
|
||||||
|
ftruncate(shmfd, MAPPED_SIZE);
|
||||||
|
|
||||||
|
// Map the segment into the processes address space
|
||||||
|
// NOTE: protection is set to allow reading and writing with a shared mapping
|
||||||
|
void* mapped_space = mmap(NULL, MAPPED_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
|
||||||
|
if(mapped_space == MAP_FAILED) {
|
||||||
|
printf("COULD NOT MMAP\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if(pid < 0) // error
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if(pid == 0) // child
|
||||||
|
{
|
||||||
|
// Child writes to shared memory segment
|
||||||
|
strcpy(mapped_space, "HELLO");
|
||||||
|
|
||||||
|
// Unmap the shared memory
|
||||||
|
munmap(mapped_space, MAPPED_SIZE);
|
||||||
|
|
||||||
|
// Close the shared memory segment
|
||||||
|
close(shmfd);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
// Wait for child to finish
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
// Parent reads from shared memory segment
|
||||||
|
printf("Parent reads %s from shared mapped segment\n", (char*)mapped_space);
|
||||||
|
|
||||||
|
// Unmap the shared memory
|
||||||
|
munmap(mapped_space, MAPPED_SIZE);
|
||||||
|
|
||||||
|
// Close the shared memory segment
|
||||||
|
close(shmfd);
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
79
Examples/ipc/ipcshm2.c
Normal file
79
Examples/ipc/ipcshm2.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* ipcshm2.c - Uses shared memory to send data from
|
||||||
|
* a child process to a parent process
|
||||||
|
* Uses shm_unlink to remove the shared memory when done
|
||||||
|
* NOTE: named shared memory segments are persistent
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <fcntl.h> // needed for parameter values for shm_open
|
||||||
|
#include <unistd.h> // needed for fork, getpid, getppid, kill system calls
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <signal.h> // needed for signal system call
|
||||||
|
#include <stdio.h> // needed for printf, perror
|
||||||
|
#include <sys/mman.h> // needed for mmap, munmap, shm system calls
|
||||||
|
#include <string.h> // needed for strcpy
|
||||||
|
|
||||||
|
#define MAPPED_SIZE 128
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Create and open a shared memory segment
|
||||||
|
int shmfd = shm_open("/CS3841MEMORY", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
|
if(shmfd == -1) {
|
||||||
|
printf("COULD NOT OPEN SHARED MEMORY SEGMENT\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the size of the shared memory segment
|
||||||
|
ftruncate(shmfd, MAPPED_SIZE);
|
||||||
|
|
||||||
|
// Map the segment into the processes address space
|
||||||
|
// NOTE: protection is set to allow reading and writing with a shared mapping
|
||||||
|
void* mapped_space = mmap(NULL, MAPPED_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
|
||||||
|
if(mapped_space == MAP_FAILED) {
|
||||||
|
printf("COULD NOT MMAP\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if(pid < 0) // error
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if(pid == 0) // child
|
||||||
|
{
|
||||||
|
// Child writes to shared memory segment
|
||||||
|
strcpy(mapped_space, "HELLO");
|
||||||
|
|
||||||
|
// Unmap the shared memory
|
||||||
|
munmap(mapped_space, MAPPED_SIZE);
|
||||||
|
|
||||||
|
// Close the shared memory segment
|
||||||
|
close(shmfd);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
// Wait for child to finish
|
||||||
|
wait(0);
|
||||||
|
|
||||||
|
// Parent reads from shared memory segment
|
||||||
|
printf("Parent reads %s from shared mapped segment\n", (char*)mapped_space);
|
||||||
|
|
||||||
|
// Unmap the shared memory
|
||||||
|
munmap(mapped_space, MAPPED_SIZE);
|
||||||
|
|
||||||
|
// Close the shared memory segment
|
||||||
|
close(shmfd);
|
||||||
|
|
||||||
|
// Unlink the shared memory
|
||||||
|
shm_unlink("/CS3841MEMORY");
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
|
||||||
46
Examples/ipc/ipcsignal.c
Normal file
46
Examples/ipc/ipcsignal.c
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* ipcsignal.c - Shows how to use the kill system call
|
||||||
|
* to send a signal from one process to another
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <sys/wait.h> // needed for wait system call
|
||||||
|
#include <unistd.h> // needed for fork, getpid, getppid, kill system calls
|
||||||
|
#include <stdlib.h> // needed for exit
|
||||||
|
#include <signal.h> // needed for signal system call
|
||||||
|
#include <stdio.h> // needed for printf, perror
|
||||||
|
|
||||||
|
void signal_handler(int sig)
|
||||||
|
{
|
||||||
|
pid_t pid = getpid();
|
||||||
|
printf("Process %d received signal %d\n", pid, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Set a signal handler for a user defined signal number 1
|
||||||
|
signal(SIGUSR1, signal_handler);
|
||||||
|
|
||||||
|
pid_t pid = fork(); // fork into 2 processes
|
||||||
|
|
||||||
|
if(pid < 0) // error
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if(pid == 0) // child
|
||||||
|
{
|
||||||
|
// Send a signal to the parent by its PID
|
||||||
|
pid_t parent_pid = getppid();
|
||||||
|
printf("Sending SIGUSR1(%d) to %d\n", SIGUSR1, parent_pid);
|
||||||
|
kill(parent_pid, SIGUSR1);
|
||||||
|
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
|
else // parent
|
||||||
|
{
|
||||||
|
// Wait for child
|
||||||
|
wait(0);
|
||||||
|
}
|
||||||
|
return 0; // Return success
|
||||||
|
}
|
||||||
29
Examples/ipc/signal1.c
Normal file
29
Examples/ipc/signal1.c
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* signal1.c - Shows how to set up a signal handler
|
||||||
|
* for the interrupt (CTRL+C) signal
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <unistd.h> // needed for getpid, sleep system calls
|
||||||
|
#include <signal.h> // needed for signal system call
|
||||||
|
#include <stdio.h> // needed for printf
|
||||||
|
|
||||||
|
// Signal handler
|
||||||
|
// Prints the PID of the process and the received signal
|
||||||
|
void signal_handler(int sig)
|
||||||
|
{
|
||||||
|
pid_t pid = getpid();
|
||||||
|
printf("Process %d received signal %d\n", pid, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Set a signal handler for the interrupt signal
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
// Loop forever and sleep
|
||||||
|
while(1) {
|
||||||
|
printf("sleeping...\n");
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Examples/ipc/signal2.c
Normal file
29
Examples/ipc/signal2.c
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* signal2.c - Shows how to set up a signal handler
|
||||||
|
* for the segmentation fault signal
|
||||||
|
* Unfortunately does not fix the segmentation
|
||||||
|
* fault and essentially loops forever
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h> // needed for pid_t
|
||||||
|
#include <unistd.h> // needed for getpid, sleep system calls
|
||||||
|
#include <signal.h> // needed for signal system call
|
||||||
|
#include <stdio.h> // needed for printf
|
||||||
|
|
||||||
|
// Signal handler
|
||||||
|
// Prints the PID of the process and the received signal
|
||||||
|
void signal_handler(int sig)
|
||||||
|
{
|
||||||
|
pid_t pid = getpid();
|
||||||
|
printf("Process %d received signal %d\n", pid, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Set up a signal handler for the segmentation fault signal
|
||||||
|
signal(SIGSEGV, signal_handler);
|
||||||
|
|
||||||
|
// Cause a segmentation fault
|
||||||
|
int* i = NULL;
|
||||||
|
return *i + 10;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user