1

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

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

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

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

所以我使用了一个非常非常非常尴尬的方法,我什至不知道它是否工作正常,但我希望你能知道,这是使用应该采用 (url,pid) 并返回密钥的 ftok。所以我假设如果我使用相同的 url 和 pid,它会发送完全相同的密钥,使用从 0 开始的假 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);
}
4

1 回答 1

1

在共享内存中,您可以插入整个链表。它在很多情况下都很有用。您不需要创建共享内存的链接列表(例如使用上一个键,下一个键)。您只需将链表的每个节点复制到共享内存即可。例如..... 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;
}

第一次运行 process1.c 然后运行 ​​process2.c

于 2016-04-30T20:37:14.263 回答