/*
* This demonstrates shared memory IPC and child inheritance of
* attached shared memory segments. Note that the IPC_PRIVATE shmget key is
* only useful for parent and child forked processes. Different processes
* must use an explicit key number, usually provided by ftok().
*
* This page is a useful supplement to the man pages.
* http://www.cs.cf.ac.uk/Dave/C/node27.html
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char **argv)
{
int rc = 1;
pid_t cpid = 0;
int shmid = 0;
struct shmid_ds shmbuf;
char *buffer = NULL;
size_t buffer_size = 4096;
int size = 0;
shmid = shmget(IPC_PRIVATE, buffer_size, IPC_CREAT | 0666);
if (shmid < 0) {
perror("shmget");
goto cleanup;
}
buffer = (char*)shmat(shmid, NULL, 0);
if (buffer < 0) {
perror("shmat");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
size = snprintf(buffer, buffer_size, "hello from child");
if (size <= 0) {
perror("snprintf");
goto cleanup;
}
printf("child wrote to shared memory buffer: %s\n", buffer);
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
wait(0);
printf("parent read from shared memory buffer: %s\n", buffer);
}
rc = 0;
cleanup:
if (buffer > 0)
shmdt(buffer);
if (shmid > 0)
shmctl(shmid, IPC_RMID, &shmbuf);
return rc;
}
[ghildstrom@hplt ipc_sysv_posix]$ ./sysv_shared_memory_private parent pid is 2164 and child pid is 2165 child pid is 2165 child wrote to shared memory buffer: hello from child parent read from shared memory buffer: hello from child
| listing | System V | POSIX |
|---|---|---|
| parent source |
/*
* This demonstrates shared memory IPC for separate processes using a file
* system path reference to shared memory. Note that the shmget key is
* derived from a path and the child execve's a totally separate process.
*
* This page is a useful supplement to the man pages.
* http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/shm/example-2.html
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char **argv)
{
int rc = 1;
pid_t cpid = 0;
key_t key = 0;
int shmid = 0;
struct shmid_ds shmbuf;
char *buffer = NULL;
size_t buffer_size = 4096;
int exec = 0;
key = ftok("shmfile", 'R');
if (key < 0) {
perror("ftok");
goto cleanup;
}
shmid = shmget(key, buffer_size, IPC_CREAT | 0666);
if (shmid < 0) {
perror("shmget");
goto cleanup;
}
buffer = (char*)shmat(shmid, NULL, 0);
if (buffer < 0) {
perror("shmat");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
exec = execve("sysv_shared_memory_file_child", NULL, NULL);
if (exec < 0) {
perror("execve");
goto cleanup;
}
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
wait(0);
printf("parent read from shared memory buffer: %s\n", buffer);
}
rc = 0;
cleanup:
if (buffer > 0)
shmdt(buffer);
if (shmid > 0)
shmctl(shmid, IPC_RMID, &shmbuf);
return rc;
}
|
/*
* This demonstrates POSIX shared memory IPC for separate processes using a
* name reference to shared memory. Note that the child execve's a totally
* separate process.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
int rc = 1;
pid_t cpid = 0;
int shmfd = 0;
char *buffer = NULL;
size_t buffer_size = 4096;
int exec = 0;
int rv = 0;
shmfd = shm_open("/shmname", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
if (shmfd < 0) {
perror("shm_open");
goto cleanup;
}
rv = ftruncate(shmfd, buffer_size);
if (rv < 0) {
perror("ftruncate");
goto cleanup;
}
buffer = mmap(NULL, buffer_size, PROT_READ, MAP_SHARED, shmfd, 0);
if (buffer < 0) {
perror("mmap");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
exec = execve("posix_shared_memory_child", NULL, NULL);
if (exec < 0) {
perror("execve");
goto cleanup;
}
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
wait(0);
printf("parent read from shared memory buffer: %s\n", buffer);
}
rc = 0;
cleanup:
if (buffer > 0)
munmap(buffer, buffer_size);
if (shmfd > 0) {
close(shmfd);
shm_unlink("/shmname");
}
return rc;
}
|
| child source |
/*
* This demonstrates shared memory IPC for separate processes using a file
* system path reference to shared memory. Note that the shmget key is
* derived from a path and this is separate from the initial forked child.
*
* This page is a useful supplement to the man pages.
* http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/shm/example-2.html
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char **argv)
{
int rc = 1;
key_t key = 0;
int shmid = 0;
char *buffer = NULL;
size_t buffer_size = 4096;
int size = 0;
key = ftok("shmfile", 'R');
if (key < 0) {
perror("ftok");
goto cleanup;
}
shmid = shmget(key, buffer_size, 0666);
if (shmid < 0) {
perror("shmget");
goto cleanup;
}
buffer = (char*)shmat(shmid, NULL, 0);
if (buffer < 0) {
perror("shmat");
goto cleanup;
}
printf("execve'd child pid is %d\n", getpid());
size = snprintf(buffer, buffer_size, "hello from execve'd child");
if (size <= 0) {
perror("snprintf");
goto cleanup;
}
printf("execve'd child wrote to shared memory buffer: %s\n", buffer);
rc = 0;
cleanup:
if (buffer > 0)
shmdt(buffer);
return rc;
}
|
/*
* This demonstrates POSIX shared memory IPC for separate processes using a
* name reference to shared memory. Note that this is separate from the
* initial forked child.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
int rc = 1;
int shmfd = 0;
char *buffer = NULL;
size_t buffer_size = 4096;
int size = 0;
shmfd = shm_open("/shmname", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
if (shmfd < 0) {
perror("shm_open");
goto cleanup;
}
buffer = mmap(NULL, buffer_size, PROT_WRITE, MAP_SHARED, shmfd, 0);
if (buffer < 0) {
perror("mmap");
goto cleanup;
}
printf("execve'd child pid is %d\n", getpid());
size = snprintf(buffer, buffer_size, "hello from execve'd child");
if (size <= 0) {
perror("snprintf");
goto cleanup;
}
printf("execve'd child wrote to shared memory buffer: %s\n", buffer);
rc = 0;
cleanup:
if (buffer > 0)
munmap(buffer, buffer_size);
if (shmfd > 0)
close(shmfd);
return rc;
}
|
| output |
[ghildstrom@hplt ipc_sysv_posix]$ ./sysv_shared_memory_file_parent parent pid is 2435 and child pid is 2436 child pid is 2436 execve'd child pid is 2436 execve'd child wrote to shared memory buffer: hello from execve'd child parent read from shared memory buffer: hello from execve'd child |
[ghildstrom@hplt ipc_sysv_posix]$ ./posix_shared_memory_parent parent pid is 2476 and child pid is 2477 child pid is 2477 execve'd child pid is 2477 execve'd child wrote to shared memory buffer: hello from execve'd child parent read from shared memory buffer: hello from execve'd child |
| listing | System V | POSIX |
|---|---|---|
| parent source |
/*
* This demonstrates semaphore IPC for separate processes using a file
* system path reference to a semaphore. Note that the semget key is
* derived from a path and the child execve's a totally separate process.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main(int argc, char **argv)
{
int rc = 1;
pid_t cpid = 0;
key_t key = 0;
int semid = 0;
struct sembuf sops[2];
int rv = 0;
int exec = 0;
key = ftok("semfile", 'R');
if (key < 0) {
perror("ftok");
goto cleanup;
}
semid = semget(key, 1, IPC_CREAT | 0666);
if (semid < 0) {
perror("semget");
goto cleanup;
}
sops[0].sem_num = 0;
sops[0].sem_op = 1;
sops[0].sem_flg = 0;
rv = semop(semid, sops, 1);
if (rv < 0) {
perror("semop");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
exec = execve("sysv_semaphore_file_child", NULL, NULL);
if (exec < 0) {
perror("execve");
goto cleanup;
}
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
sleep(1);
printf("parent delay\n");
sleep(2);
printf("parent about to decrement semaphore back to zero\n");
sops[0].sem_op = -1;
rv = semop(semid, sops, 1);
if (rv < 0) {
perror("semop");
goto cleanup;
}
wait(0);
}
rc = 0;
cleanup:
if (semid > 0)
semctl(semid, 1, IPC_RMID);
return rc;
}
|
/*
* This demonstrates POSIX semaphore IPC for separate processes using a
* name reference to a semaphore. Note that the child execve's a totally
* separate process.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
int main(int argc, char **argv)
{
int rc = 1;
pid_t cpid = 0;
sem_t *sem = NULL;
int rv = 0;
int exec = 0;
sem = sem_open("/semname", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0);
if (sem == SEM_FAILED) {
perror("sem_open");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
exec = execve("posix_semaphore_child", NULL, NULL);
if (exec < 0) {
perror("execve");
goto cleanup;
}
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
sleep(1);
printf("parent delay\n");
sleep(2);
printf("parent about to increment semaphore to non-zero\n");
rv = sem_post(sem);
if (rv < 0) {
perror("sem_post");
goto cleanup;
}
wait(0);
}
rc = 0;
cleanup:
if (sem != SEM_FAILED) {
sem_close(sem);
sem_unlink("/semname");
}
return rc;
}
|
| child source |
/*
* This demonstrates semaphore IPC for separate processes using a file
* system path reference to a semaphore. Note that the semget key is
* derived from a path and this is separate from the initial forked child.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main(int argc, char **argv)
{
int rc = 1;
key_t key = 0;
int semid = 0;
struct sembuf sops[2];
int rv = 0;
key = ftok("semfile", 'R');
if (key < 0) {
perror("ftok");
goto cleanup;
}
semid = semget(key, 1, 0666);
if (semid < 0) {
perror("semget");
goto cleanup;
}
printf("execve'd child pid is %d\n", getpid());
printf("execve'd child waiting for semaphore zero value\n");
sops[0].sem_num = 0;
sops[0].sem_op = 0;
sops[0].sem_flg = 0;
rv = semop(semid, sops, 1);
if (rv < 0) {
perror("semop");
goto cleanup;
}
printf("execve'd child detected semaphore zero value\n");
rc = 0;
cleanup:
return rc;
}
|
/*
* This demonstrates POSIX semaphore IPC for separate processes using a
* name reference to a semaphore. Note that this is separate from the
* initial forked child.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
int main(int argc, char **argv)
{
int rc = 1;
sem_t *sem = NULL;
int rv = 0;
sem = sem_open("/semname", O_RDWR);
if (sem == SEM_FAILED) {
perror("sem_open");
goto cleanup;
}
printf("execve'd child pid is %d\n", getpid());
printf("execve'd child waiting for semaphore non-zero value\n");
rv = sem_wait(sem);
if (rv < 0) {
perror("sem_wait");
goto cleanup;
}
printf("execve'd child detected semaphore non-zero value\n");
rc = 0;
cleanup:
if (sem != SEM_FAILED)
sem_close(sem);
return rc;
}
|
| output |
[ghildstrom@hplt ipc_sysv_posix]$ ./sysv_semaphore_file_parent parent pid is 2899 and child pid is 2900 child pid is 2900 execve'd child pid is 2900 execve'd child waiting for semaphore zero value parent delay parent about to decrement semaphore back to zero execve'd child detected semaphore zero value |
[ghildstrom@hplt ipc_sysv_posix]$ ./posix_semaphore_parent parent pid is 2925 and child pid is 2926 child pid is 2926 execve'd child pid is 2926 execve'd child waiting for semaphore non-zero value parent delay parent about to increment semaphore to non-zero execve'd child detected semaphore non-zero value |
| listing | System V | POSIX |
|---|---|---|
| parent source |
/*
* This demonstrates message queue IPC for separate processes using a file
* system path reference to a message queue. Note that the msgget key is
* derived from a path and the child execve's a totally separate process.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
long mtype;
char mtext[1];
};
int main(int argc, char **argv)
{
int rc = 1;
pid_t cpid = 0;
key_t key = 0;
int msgid = 0;
struct msqid_ds msgds;
struct msgbuf msg;
int rv = 0;
int exec = 0;
key = ftok("msgfile", 'R');
if (key < 0) {
perror("ftok");
goto cleanup;
}
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid < 0) {
perror("msgget");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
exec = execve("sysv_message_queue_file_child", NULL, NULL);
if (exec < 0) {
perror("execve");
goto cleanup;
}
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
sleep(1);
printf("parent delay\n");
sleep(2);
printf("parent about to send message\n");
msg.mtype = 1234;
rv = msgsnd(msgid, &msg, 0, 0);
if (rv < 0) {
perror("msgsnd");
goto cleanup;
}
wait(0);
}
rc = 0;
cleanup:
if (msgid > 0)
msgctl(msgid, IPC_RMID, &msgds);
return rc;
}
|
/*
* This demonstrates POSIX message queue IPC for separate processes using a
* name reference to a message queue. Note that the child execve's a totally
* separate process.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
int main(int argc, char **argv)
{
int rc = 1;
pid_t cpid = 0;
key_t key = 0;
mqd_t msgid = 0;
struct mq_attr attr;
char *msg = NULL;
int rv = 0;
int exec = 0;
msg = (char*)malloc(1024);
if (!msg) {
perror("msg");
goto cleanup;
}
attr.mq_flags = O_RDWR;
attr.mq_maxmsg = 10;
attr.mq_msgsize = 1024;
attr.mq_curmsgs = 0;
msgid = mq_open("/msgname", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, &attr);
if (msgid < 0) {
perror("mq_open");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
exec = execve("posix_message_queue_child", NULL, NULL);
if (exec < 0) {
perror("execve");
goto cleanup;
}
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
sleep(1);
printf("parent delay\n");
sleep(2);
printf("parent about to send message\n");
rv = snprintf(msg, 1024, "1234");
if (rv <= 0) {
perror("snprintf");
goto cleanup;
}
rv = mq_send(msgid, msg, strlen(msg), 0);
if (rv < 0) {
perror("mq_send");
goto cleanup;
}
wait(0);
}
rc = 0;
cleanup:
if (msgid > 0) {
mq_close(msgid);
mq_unlink("/msgname");
}
return rc;
}
|
| child source |
/*
* This demonstrates message queue IPC for separate processes using a file
* system path reference to a message queue. Note that the msgget key is
* derived from a path and this is separate from the initial forked child.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
long mtype;
char mtext[1];
};
int main(int argc, char **argv)
{
int rc = 1;
key_t key = 0;
int msgid = 0;
struct msgbuf msg;
ssize_t rv = 0;
key = ftok("msgfile", 'R');
if (key < 0) {
perror("ftok");
goto cleanup;
}
msgid = msgget(key, 0666);
if (msgid < 0) {
perror("msgget");
goto cleanup;
}
printf("execve'd child pid is %d\n", getpid());
printf("execve'd child waiting for message\n");
rv = msgrcv(msgid, &msg, 0, 0, 0);
if (rv < 0) {
perror("msgrcv");
goto cleanup;
}
printf("execve'd child received message type %d\n", msg.mtype);
rc = 0;
cleanup:
return rc;
}
|
/*
* This demonstrates POSIX message queue IPC for separate processes using a
* name reference to a message queue. Note that this is separate from the
* initial forked child.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
int main(int argc, char **argv)
{
int rc = 1;
key_t key = 0;
mqd_t msgid = 0;
char *msg = NULL;
ssize_t rv = 0;
msg = (char*)malloc(1024);
if (!msg) {
perror("malloc");
goto cleanup;
}
msgid = mq_open("/msgname", O_RDONLY);
if (msgid < 0) {
perror("mq_open");
goto cleanup;
}
printf("execve'd child pid is %d\n", getpid());
printf("execve'd child waiting for message\n");
rv = mq_receive(msgid, msg, 1024, NULL);
if (rv < 0) {
perror("mq_receive");
goto cleanup;
}
printf("execve'd child received message %s\n", msg);
rc = 0;
cleanup:
free(msg);
if (msgid > 0)
mq_close(msgid);
return rc;
}
|
| output |
[ghildstrom@hplt ipc_sysv_posix]$ ./sysv_message_queue_file_parent parent pid is 2965 and child pid is 2966 child pid is 2966 execve'd child pid is 2966 execve'd child waiting for message parent delay parent about to send message execve'd child received message type 1234 |
[ghildstrom@hplt ipc_sysv_posix]$ ./posix_message_queue_parent parent pid is 2992 and child pid is 2993 child pid is 2993 execve'd child pid is 2993 execve'd child waiting for message parent delay parent about to send message execve'd child received message 1234 |
all: sysv posix clean: sysv_clean posix_clean sysv: \ sysv_shared_memory_private \ shmfile \ sysv_shared_memory_file_parent \ sysv_shared_memory_file_child \ semfile \ sysv_semaphore_file_parent \ sysv_semaphore_file_child \ msgfile \ sysv_message_queue_file_parent \ sysv_message_queue_file_child sysv_shared_memory_private: sysv_shared_memory_private.c gcc -o sysv_shared_memory_private sysv_shared_memory_private.c shmfile: touch shmfile sysv_shared_memory_file_parent: sysv_shared_memory_file_parent.c gcc -o sysv_shared_memory_file_parent sysv_shared_memory_file_parent.c sysv_shared_memory_file_child: sysv_shared_memory_file_child.c gcc -o sysv_shared_memory_file_child sysv_shared_memory_file_child.c semfile: touch semfile sysv_semaphore_file_parent: sysv_semaphore_file_parent.c gcc -o sysv_semaphore_file_parent sysv_semaphore_file_parent.c sysv_semaphore_file_child: sysv_semaphore_file_child.c gcc -o sysv_semaphore_file_child sysv_semaphore_file_child.c msgfile: touch msgfile sysv_message_queue_file_parent: sysv_message_queue_file_parent.c gcc -o sysv_message_queue_file_parent sysv_message_queue_file_parent.c sysv_message_queue_file_child: sysv_message_queue_file_child.c gcc -o sysv_message_queue_file_child sysv_message_queue_file_child.c sysv_clean: rm -f sysv_shared_memory_private rm -f shmfile rm -f sysv_shared_memory_file_parent rm -f sysv_shared_memory_file_child rm -f semfile rm -f sysv_semaphore_file_parent rm -f sysv_semaphore_file_child rm -f msgfile rm -f sysv_message_queue_file_parent rm -f sysv_message_queue_file_child posix: \ posix_shared_memory_parent \ posix_shared_memory_child \ posix_semaphore_parent \ posix_semaphore_child \ posix_message_queue_parent \ posix_message_queue_child posix_shared_memory_parent: posix_shared_memory_parent.c gcc -lrt -o posix_shared_memory_parent posix_shared_memory_parent.c posix_shared_memory_child: posix_shared_memory_child.c gcc -lrt -o posix_shared_memory_child posix_shared_memory_child.c posix_semaphore_parent: posix_semaphore_parent.c gcc -pthread -o posix_semaphore_parent posix_semaphore_parent.c posix_semaphore_child: posix_semaphore_child.c gcc -pthread -o posix_semaphore_child posix_semaphore_child.c posix_message_queue_parent: posix_message_queue_parent.c gcc -lrt -o posix_message_queue_parent posix_message_queue_parent.c posix_message_queue_child: posix_message_queue_child.c gcc -lrt -o posix_message_queue_child posix_message_queue_child.c posix_clean: rm -f posix_shared_memory_parent rm -f posix_shared_memory_child rm -f posix_semaphore_parent rm -f posix_semaphore_child rm -f posix_message_queue_parent rm -f posix_message_queue_child