Memory 具有共享内存的指针和链表

Memory 具有共享内存的指针和链表,memory,linked-list,shared,Memory,Linked List,Shared,我想让两个程序进行通信,一个(服务器)存储数据,另一个(客户端)访问数据。 我将不得不使用链表来存储数据,因为它不会停止存储,然后我想知道如果只有第一个节点在内存中共享,是否可以访问整个链表 我的意思是…我们可以从客户端程序访问共享指针指向的内存吗 很抱歉,显然我们不能,所以我应该将我的链接列表存储到共享内存中,还是您认为这会很尴尬? 因为如果我这样做,我必须为每个节点声明一个共享内存,对吗 所以,要为两个程序添加共享内存,我需要相同的键,但我不知道会有多少键,而且我不能只为两个程序存储它,除非

我想让两个程序进行通信,一个(服务器)存储数据,另一个(客户端)访问数据。 我将不得不使用链表来存储数据,因为它不会停止存储,然后我想知道如果只有第一个节点在内存中共享,是否可以访问整个链表

我的意思是…我们可以从客户端程序访问共享指针指向的内存吗

很抱歉,显然我们不能,所以我应该将我的链接列表存储到共享内存中,还是您认为这会很尴尬? 因为如果我这样做,我必须为每个节点声明一个共享内存,对吗

所以,要为两个程序添加共享内存,我需要相同的键,但我不知道会有多少键,而且我不能只为两个程序存储它,除非我已经有一个链接列表

所以我使用了一个非常非常笨拙的方法,我甚至不知道它是否工作正常,但我希望你能告诉我,那就是使用ftok,它应该接受一个(url,pid)并返回一个键。因此,我假设如果我使用相同的url和pid,它将发送完全相同的键,使用从0开始的伪pid,我将为添加到链接列表中的每个元素递增该pid…您对此有何看法?有没有其他的方法看起来不那么…糟糕

typedef struct s_shared_elem
{
    char c;
    struct s_shared_elem* next;
    struct s_shared_elem* previous;
}shared_elem;

typedef struct s_shared_list
{
    s_shared_elem* first;
    s_shared_elem* last;
}shared_list;

int forthekey = 0;
char* url="/home/toor/Projet_cgi/";

shared_elem* shared_malloc(int pid, const char* url)
{
        shared_elem* shm;
        int shmid;
        int key=ftok(url,pid);
        if((shmid=shmget(key,1,IPC_CREAT | 0666)) < 0)
        {   
            perror("shmget");
            exit(1);
        }   

        if ((shm = shmat(shmid,NULL,0)) == (shared_elem*)-1)
        {
             perror("shmat");
             exit(1);
        }
        return shm;
}

void Init_shared_list(shared_list* liste)
{
    liste->first = NULL;
    liste->last = NULL;
}

void Add_elem(shared_list* liste)
{
    shared_elem* new = shared_malloc(pid,url);
    new->next = NULL;
    new->previous = liste->last;

    if(liste->first == NULL)
    {
        liste->first = new;
        liste->last = new;
    }

    else
    {
        liste->last->next = new;
        liste->last = new;
    }

    forthekey++;
}

void shared_free(shared_elem* todelete,int pid, const char* url)
{
    shared_elem* shm;
    int shmid;
    int key=ftok(url,pid);
    if((shmid=shmget(key,1,IPC_CREAT | 0666)) < 0)
    {
        perror("shmget");
        exit(1);
    }
    shmdt(todelete);
    shmctl(shmid,IPC_RMID,NULL);

    forthekey--;
}

void Delete_list(shared_list* liste)
{
    while(liste->last != liste->first)
    {
        shared_elem* tmp=liste->last;
        liste->last=liste->last->previous;
        Shared_free(tmp,pid,url);
    }
    Shared_free(liste->first,pid,url);
}
typedef结构共享元素
{
字符c;
结构s_共享元素*next;
结构s_共享元素*上一个;
}共享元素;
typedef结构s_共享_列表
{
首先是共享元素;
s_shared_elem*last;
}共享列表;
int forthekey=0;
char*url=“/home/toor/Projet_cgi/”;
共享元素*共享元素(整型pid,常量字符*url)
{
共享元素*shm;
int shmid;
int key=ftok(url,pid);
如果((shmid=shmget(键,1,IPC|U创建| 0666))<0)
{   
佩罗尔(“shmget”);
出口(1);
}   
如果((shm=shmat(shmid,NULL,0))==(共享元素*)-1)
{
佩罗尔(“shmat”);
出口(1);
}
返回shm;
}
void Init_shared_list(shared_list*liste)
{
liste->first=NULL;
liste->last=NULL;
}
无效添加元素(共享列表*列表)
{
shared_elem*new=shared_malloc(pid,url);
新建->下一步=空;
新建->上一个=列表->上一个;
if(liste->first==NULL)
{
liste->first=新建;
liste->last=新建;
}
其他的
{
liste->last->next=新建;
liste->last=新建;
}
forthekey++;
}
void shared\u free(shared\u elem*todelete、int pid、const char*url)
{
共享元素*shm;
int shmid;
int key=ftok(url,pid);
如果((shmid=shmget(键,1,IPC|U创建| 0666))<0)
{
佩罗尔(“shmget”);
出口(1);
}
shmdt(托德莱特);
shmctl(shmid,IPC\u RMID,NULL);
对于关键--;
}
作废删除列表(共享列表*列表)
{
while(liste->last!=liste->first)
{
共享元素*tmp=liste->last;
列表->最后一个=列表->最后一个->上一个;
免费共享(tmp、pid、url);
}
免费共享(列表->第一,pid,url);
}

在共享内存中,您可以插入整个链表。它在许多情况下都很有用。您不需要创建共享内存的链接列表(例如,使用上一个键、下一个键)。您只需将链表的每个节点复制到共享内存即可。 例如 过程2.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h> 
int main(int argc, char *argv[])
{
    int shmid,i;
    node *data; 
    if ((shmid = shmget(10, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *)shmat(shmid, (void *)0, 0);  // node is linked list
    for(i=0;i<2;i++)
    printf("%d\n",(data++)->item_code);

    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

process1.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main(int argc, char *argv[])
{
    node *SELL=NULL;     // node is linked list (structure) SELL is header
    insert(&SELL,"Soap",1,12.5,10);
    insert(&SELL,"Pen",2,20.75,8);
    display(SELL);

    int shmid,i;
    node *data;

    if ((shmid = shmget(10, 2*sizeof(node), 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *) shmat(shmid, (void *)0, 0);
    for(i=0;i<2;i++)
    {
        *(data++)=*SELL;
        SELL=SELL->next;
    }
    getchar();
    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }
shmctl(shmid, IPC_RMID, NULL);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
内特希米德,我;
节点*数据;
如果((shmid=shmget(10,SHM|U大小,0644|IPC|U创建))=-1){
佩罗尔(“shmget”);
出口(1);
}
data=(node*)shmat(shmid,(void*)0,0);//节点是链表
用于(i=0;项目代码);
如果(shmdt(数据)=-1){
佩罗(“shmdt”);
出口(1);
}
返回0;
}
过程1.c
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
node*SELL=NULL;//节点为链表(结构)SELL为表头
插入并出售“肥皂”,1,12.5,10);
插入并出售“笔”,2,20.75,8);
展示(出售);
内特希米德,我;
节点*数据;
如果((shmid=shmget(10,2*sizeof(node),0644 | IPC_CREAT))=-1){
佩罗尔(“shmget”);
出口(1);
}
数据=(节点*)shmat(shmid,(void*)0,0;
对于(i=0;不精确;
}
getchar();
如果(shmdt(数据)=-1){
佩罗(“shmdt”);
出口(1);
}
shmctl(shmid,IPC\u RMID,NULL);
返回0;
}

首先运行process1.c,然后在共享内存中运行process2.c。您可以插入一个完整的链表。这在许多情况下都很有用。您不需要创建共享内存的链表(例如,使用上一个键、下一个键)。只需将链表的每个节点复制到共享内存中即可。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h> 
int main(int argc, char *argv[])
{
    int shmid,i;
    node *data; 
    if ((shmid = shmget(10, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *)shmat(shmid, (void *)0, 0);  // node is linked list
    for(i=0;i<2;i++)
    printf("%d\n",(data++)->item_code);

    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

process1.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main(int argc, char *argv[])
{
    node *SELL=NULL;     // node is linked list (structure) SELL is header
    insert(&SELL,"Soap",1,12.5,10);
    insert(&SELL,"Pen",2,20.75,8);
    display(SELL);

    int shmid,i;
    node *data;

    if ((shmid = shmget(10, 2*sizeof(node), 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *) shmat(shmid, (void *)0, 0);
    for(i=0;i<2;i++)
    {
        *(data++)=*SELL;
        SELL=SELL->next;
    }
    getchar();
    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }
shmctl(shmid, IPC_RMID, NULL);
    return 0;
}
例如 过程2.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h> 
int main(int argc, char *argv[])
{
    int shmid,i;
    node *data; 
    if ((shmid = shmget(10, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *)shmat(shmid, (void *)0, 0);  // node is linked list
    for(i=0;i<2;i++)
    printf("%d\n",(data++)->item_code);

    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

process1.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main(int argc, char *argv[])
{
    node *SELL=NULL;     // node is linked list (structure) SELL is header
    insert(&SELL,"Soap",1,12.5,10);
    insert(&SELL,"Pen",2,20.75,8);
    display(SELL);

    int shmid,i;
    node *data;

    if ((shmid = shmget(10, 2*sizeof(node), 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *) shmat(shmid, (void *)0, 0);
    for(i=0;i<2;i++)
    {
        *(data++)=*SELL;
        SELL=SELL->next;
    }
    getchar();
    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }
shmctl(shmid, IPC_RMID, NULL);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
内特希米德,我;
节点*数据;
如果((shmid=shmget(10,SHM|U大小,0644|IPC|U创建))=-1){
佩罗尔(“shmget”);
出口(1);
}
data=(node*)shmat(shmid,(void*)0,0);//节点是链表
用于(i=0;项目代码);
如果(shmdt(数据)=-1){
佩罗(“shmdt”);
出口(1);
}
返回0;
}
过程1.c
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
node*SELL=NULL;//节点为链表(结构)SELL为表头
插入并出售“肥皂”,1,12.5,10);
插入并出售“笔”,2,20.75,8);
展示(出售);
内特希米德,我;
节点*数据;
如果((shmid=shmget(10,2*sizeof(node),0644 | IPC_CREAT))=-1){
佩罗尔(“shmget”);
出口(1);
}
数据=(节点*)shmat(shmid,(void*)0,0;
对于(i=0;不精确;
}
getchar();
如果(shmdt(数据)=-1){
佩罗(“shmdt”);
出口(1);
}
shmctl(shmid,IPC\u RMID,NULL);
返回0;
}

首先运行process1.c,然后运行process2.c

假设可以计算出最大的总内存需求,并且在合理的范围内,我可能会预先分配一个足够大的shar
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h> 
int main(int argc, char *argv[])
{
    int shmid,i;
    node *data; 
    if ((shmid = shmget(10, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *)shmat(shmid, (void *)0, 0);  // node is linked list
    for(i=0;i<2;i++)
    printf("%d\n",(data++)->item_code);

    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

process1.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main(int argc, char *argv[])
{
    node *SELL=NULL;     // node is linked list (structure) SELL is header
    insert(&SELL,"Soap",1,12.5,10);
    insert(&SELL,"Pen",2,20.75,8);
    display(SELL);

    int shmid,i;
    node *data;

    if ((shmid = shmget(10, 2*sizeof(node), 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }


    data = (node *) shmat(shmid, (void *)0, 0);
    for(i=0;i<2;i++)
    {
        *(data++)=*SELL;
        SELL=SELL->next;
    }
    getchar();
    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }
shmctl(shmid, IPC_RMID, NULL);
    return 0;
}