简体   繁体   中英

One Process per Client Server using Shared Memory in C

I am creating an "One Process per Client" server using the TCP protocol for academic purpose.

I use a global struct like the one bellow:

struct keyvalue
    {
        char a[4096];
        char b[4096];
    }data[1000];

I use fork() to create a child for each client.

I know that each child sees this struct as an exact copy of the parent process however if a child makes a change it is not visible to the other children and this is my goal.

I searched in google for hours and the only proper solution i found is mmap()

Bellow I present how i tried to solve this task:

int main ( int argc, char *argv[])
{
for(int c = 0; c < 1000 ; c++)
    {
        data[c] = mmap(NULL, sizeof(data[c]), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

    }
.
.
.
return 0;
}

However I think that I haven't understand properly the use of this function and the documentation didn't help for this project.

It would be great if someone explained to me the exact way to use this function for my project. EDIT:

This global struct is used by two global function:

void put(char *key, char *value)
{
.
.
.       
strcpy(data[lp].keys,key);
strcpy(data[lp].values,value);
.
.
.   
}

Thank you in behave and sorry for my bad English.

You can use the following piece of code to create an array of structs that is shared across multiple forked processes.

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define MAX_LEN 10000

struct region {
        int len;
        char buf[MAX_LEN];

};

int fd;

int main(void){

        //Create shared memory
        fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
        if (fd == -1)
                printf("Error: shm_open\n");

        //Expand to meet the desirable size
        if (ftruncate(fd, MAX_LEN*sizeof(struct region)) == -1)
                printf("Error: ftruncate\n");



        pid_t pid = fork();
        if (pid == 0){
                struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
                if (ptr == MAP_FAILED)
                        printf("Error\n");


                memset(ptr, 0, 50*sizeof(struct region));
                usleep(1500000);
                ptr[33].len = 42;

        }else if (pid > 0){
                struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
                if (ptr == MAP_FAILED)
                        printf("Error\n");


                usleep(1000000);
                printf("Value before: %d\n", ptr[33].len);
                usleep(1000000);
                printf("Value after: %d\n", ptr[33].len);

        }else{
                printf("Error: fork\n");
        }

        shm_unlink("/myregion");

        return 0;
}

Compilation: gcc -o shmem_test shmem_test.c -lrt

EDIT: If you can't use shm_open, alternatively you can do the following in your main function:

int main(void){

        struct region * ptr = mmap(NULL, MAX_LEN*sizeof(struct region), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED,-1,0);
        pid_t pid = fork();
        if (pid == 0){

                usleep(1500000);
                ptr[33].len = 42;

        }else if (pid > 0){

                usleep(1000000);
                printf("Value before: %d\n", ptr[33].len);
                usleep(1000000);
                printf("Value after: %d\n", ptr[33].len);

        }else{
                printf("Error: fork\n");
        }

        return 0;
}

The difference between the two, is that shm_open creates a named shared memory, which means that different processes in different executables can map this memory, given that they have the struct region definition. In the second case this cannot be done, ie the shared memory is anonymous.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM