C Programming

Shmget 2 C Function

The shmget() function is used to build a new message queue or to get access to an existing one. Shared memory is among the inter-process communication methods that permits two or more processes to quickly interchange the data and communicate in the user space. Shared memory refers to when numerous processes access the same memory region and can modify or access it as needed. To clarify, each process has its memory address; if a process wishes to transmit the data from its system memory to the other processes, only the inter-process communication IPC mechanisms are available.

Communication can occur between the systems that are connected or unrelated, as we are all aware. The shmget system call method is used to either establish a new shared memory segment or locate an existing one using a key. Shared memory segments are memory sections that can be accessed by several processes and that, once established, remains available until they are explicitly destroyed with the shmctl function. This article will show you how to use the shmget system call function in C language to allocate the shared memory in a variety of ways.

Syntax of the Shmget System Call Function in C Language

int shmget(key_t key, size_t size, int shmflg);

Here, we have a general syntax of the shmget system call function. There are different parameters passed in the shmget function. These parameters are explained in details in the following discussion.

The value of the parameter key is returned by shmget() which returns the identification shared memory segment of the System V. If the key is IPC PRIVATE or not IPC PRIVATE, no shared memory segment equivalent to the key exists, and the IPC CREAT is defined in shmflg, a new shared memory segmentation with a size equivalent to the value of the size scaled up to a multiple PAGE SIZE is produced. (This is similar to the open(2) effect of O CREAT | O EXCL).

The segment’s needed size is specified by the size argument. If the segment presently occurs, the size cannot exceed the size provided when it was created. Furthermore, to define which users are authorized to access or change the memory segment, any of the authority bits S IRUSR, S IWUSR, S IRGRP, S IWGRP, S IROTH, and S IWOTH may be supplied.

Example

The example code shows how to use the shmget and shmat system call functions in a single process to create a new shared segment and afterward write some text into it. The sample code also shows that the multiple processes can transmit using the collective memory.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <pthread.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/shm.h>

enum {SEGMENT_SIZE = 0x6400};

const char *data = "Hey, there!";

int main(int argc, char *argv[]) {

    int status;
    int segment_id;

    segment_id = shmget (IPC_PRIVATE, SEGMENT_SIZE,
                        IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
    char *sh_mem = (char *) shmat(segment_id, 0, 0);

    printf("Segment ID %d\n", segment_id);
    printf("Attached at %p\n", sh_mem);
    memmove(sh_mem, data, strlen(data)+1);
    printf("%s\n", sh_mem);

    pid_t child_pid = fork();
    if (child_pid == -1)
        perror("fork");

    if (child_pid == 0) {
        strcpy(sh_mem, "NEW DATA in Child Process\0");

        printf("child pid : %d\n", getpid());
        exit(EXIT_SUCCESS);
    } else {
        pid_t ret = waitpid(child_pid, &status, WUNTRACED | WCONTINUED);
        if (ret == -1)
            perror("waitpid");

        if (WIFEXITED(status))
            printf("Status of child exited : %d\n", WEXITSTATUS(status));

        if (WEXITSTATUS(status) == 0)
            printf("%s\n", sh_mem);
    }

    shmdt(sh_mem);
    shmctl(segment_id, IPC_RMID, 0);
    exit(EXIT_SUCCESS);
}

First, we included some applicable header files. The shared memory capability is defined in the “sys/shm.h” header file. Begin with the code implementation. We defined the size of the segment by utilizing the enum method. The variable is declared as the data where the string is initialized. Then, we have the main function call. In the main function of this example, the variables are defined and initialized. The segement_id is initialized with the shmget method. The memory segment key is the first of the three arguments passed to the shmget method. If a new segment requires to be established, the key value can be the IPC PRIVATE macro or the key value of an existing segment if the call needs to get the memory identification.

The size of the segment is specified by the second argument and the permission flags, which can be OR-ed to add possible values, are specified by the third argument of shmget.

The segment identifier is received after the memory segment is formed, and it can then be sent to the shmat function to connect the memory segment. As a second input to shmat, the user can specify the address where the memory segment should be attached. Still, it’s more common to allow the kernel to determine the address and use NULL to indicate that. The printf function prints the segment id value and the attached shared memory and prints the “Hey, there” string.

The primary process “pid_t” forks and a child process “child_pid” are generated, each of which saves a distinct string in the same address. In the meantime, the parent process halts and waits for the child to finish then leaves with a successful code. The newly saved string is written to the console. If many processes need to alter and acquire the shared memory segments at the same time, synchronization techniques such as semaphores must be used.

The execution of the previous code generates an output like this. The segment id is generated, the shared memory address is displayed, and the string is also printed on the prompt. The child pid and the status of the child exited are generated along with the message, “NEW DATA in child process”.

Conclusion

We went over the shmget system call function in great detail in this post. The shmget() function retrieves the key’s shared memory identification. Through the shmget system call function, we can get the shared memory.  Before we can use the shmget() function, we need to import many libraries. This function contains the parameters that control a variety of functions. This post helps you enhance your programming skills and address the issues that you may have had about the shmget system call function.

About the author

Omar Farooq

Hello Readers, I am Omar and I have been writing technical articles from last decade. You can check out my writing pieces.