2013-05-20 70 views
1

链表我想2个程序进行通信,一个(服务器)将存储上传数据,其他的(客户端)将只访问它。 我将不得不使用链表存储DATAS,因为它不会停止存储,然后我在想,如果如果只有第一个节点是在内存中共享我可以访问整个链表。指针和共享内存

我的意思是......我们现在可以从客户端程序访问通过一个共享的指针指向内存?

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

所以,共享内存添加到这两个项目,我需要相同的密钥,但我不知道有多少键就会出现,我不能只将其存储这两个程序,除非我本来就已经一个链表...

所以我用了一个非常非常非常尴尬的方法,我甚至不知道它是否正常工作,但是我希望你可以告诉,这是使用ftok,应该采取(url, pid)并返回一个密钥。所以我认为它会发送完全相同的密钥,如果我使用相同的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); 
} 
+1

假设最大总存储器需求可以被计算并且是合理的界限内,我可能只需预先分配足够大的共享缓冲区,然后使用偏移量作为参考。如果您的数据非常动态,您可以在同一个块内维护一个链接的空闲块列表,也可以基于偏移量。 –

+0

我从USB上获取数据,并且我收集的数据数量取决于时间,每秒一次......我必须承认,3600个元素的缓冲区需要1个小时才能填满。你认为我应该走这条路?更容易传递的缓冲区,但也有一个限制(以链表,以及你会说,你的内存有限制本身) – toor

+0

有关使用数据库来存储数据是什么? –

回答

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