每个客户端服务器使用C中的共享内存一个进程

时间:2017-04-25 11:48:20

标签: c linux tcp server mmap

我正在使用TCP协议为学术目的创建一个"每个客户一个进程" 服务器。

我使用的全局结构如下:

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

我使用fork()为每个客户端创建一个子节点。

我知道每个孩子都认为这个结构是父进程的精确副本,但是如果一个孩子进行了更改,那么其他孩子看不到它,这是我的目标。

我在谷歌搜索了几个小时,我找到的唯一合适的解决方案是mmap()

贝娄我介绍了我是如何尝试解决这个问题的:

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;
}

但是我认为我还没有正确理解这个功能的使用,文档对这个项目没有帮助。

如果有人向我解释了为我的项目使用此功能的确切方法,那将会很棒。 修改

这个全局结构由两个全局函数使用:

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

谢谢你的举止并抱歉我的英语不好。

1 个答案:

答案 0 :(得分:0)

您可以使用以下代码段来创建跨多个分叉进程共享的结构数组。

#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;
}

编译:{{1​​}}

编辑:如果您不能使用shm_open,或者您可以在主函数中执行以下操作:

gcc -o shmem_test shmem_test.c -lrt

两者之间的区别在于,shm_open创建了一个命名共享内存,这意味着不同可执行文件中的不同进程可以映射此内存,因为它们具有结构区域定义。在第二种情况下,这是不可能的,即共享存储器是匿名的。