2011-08-30 17 views
12

मैं दो प्रक्रियाओं के बीच संवाद करने की कोशिश कर रहा हूं। मैं एक प्रक्रिया में साझा स्मृति में डेटा (जैसे नाम, फोन नंबर, पता) को सहेजने की कोशिश कर रहा हूं और अन्य प्रक्रिया के माध्यम से उस डेटा को मुद्रित करने का प्रयास कर रहा हूं।दो प्रक्रियाओं के बीच संवाद करने के लिए साझा स्मृति का उपयोग कैसे करें

process1.c

#include <stdio.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
int main() 
{ 
    int segment_id; 
    char* shared_memory[3]; 
    int segment_size; 
    key_t shm_key; 
    int i=0; 
    const int shared_segment_size = 0x6400; 
    /* Allocate a shared memory segment. */ 
    segment_id = shmget (shm_key, shared_segment_size, 
      IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); 
    /* Attach the shared memory segment. */ 
    shared_memory[3] = (char*) shmat (segment_id, 0, 0); 
    printf ("shared memory attached at address %p\n", shared_memory); 
    /* Write a string to the shared memory segment. */ 
    sprintf(shared_memory[i], "maddy \n"); 
    sprintf(shared_memory[i+1], "73453916\n"); 
    sprintf(shared_memory[i+2], "america\n"); 

    /*calling the other process*/ 
    system("./process2"); 

    /* Detach the shared memory segment. */ 
    shmdt (shared_memory); 
    /* Deallocate the shared memory segment.*/ 
    shmctl (segment_id, IPC_RMID, 0); 

    return 0; 
} 

process2.c

#include <stdio.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
int main() 
{ 
    int segment_id; 
    char* shared_memory[3]; 
    int segment_size; 
    int i=0; 
    key_t shm_key; 
    const int shared_segment_size = 0x6400; 
    /* Allocate a shared memory segment. */ 
    segment_id = shmget (shm_key, shared_segment_size, 
       S_IRUSR | S_IWUSR); 
    /* Attach the shared memory segment. */ 
    shared_memory[3] = (char*) shmat (segment_id, 0, 0); 
    printf ("shared memory22 attached at address %p\n", shared_memory); 
    printf ("name=%s\n", shared_memory[i]); 
    printf ("%s\n", shared_memory[i+1]); 
    printf ("%s\n", shared_memory[i+2]); 
    /* Detach the shared memory segment. */ 
    shmdt (shared_memory); 
    return 0; 
} 

लेकिन मैं वांछित आउटपुट नहीं मिल रहा है। उत्पादन जो मुझे मिल गया है:

shared memory attached at address 0x7fff0fd2d460 
Segmentation fault 

किसी को भी मुझे इस के साथ मदद कृपया कर सकते हैं। क्या यह shared_memory[3] आरंभ करने का सही तरीका है।

धन्यवाद।

उत्तर

14
char* shared_memory[3]; 
... 
shared_memory[3] = (char*) shmat (segment_id, 0, 0); 

आप चार को तीन संकेत पकड़े करने में सक्षम एक सरणी के रूप में shared_memory घोषित है, लेकिन क्या आप वास्तव में यह के साथ क्या एक सूचक सरणी के अंत के पीछे एक ही स्थान पर लिखने के लिए है। चूंकि वहां कोई बात नहीं है कि अन्यथा स्मृति का उपयोग किस प्रकार किया जाता है, आगे क्या होता है आम तौर पर अप्रत्याशित होता है।

shared_memory[0]shared_memory[2] के माध्यम से पॉइंटर्स का उपयोग करने का प्रयास करते समय चीजें बाद में खराब होती हैं, क्योंकि उन पॉइंटर्स को कभी प्रारंभ नहीं किया गया है। वे ढेर से अर्थहीन कचरे से भरे हुए हैं - इस प्रकार सेगमेंटेशन गलती।

ऐसा लगता है कि आप सरणी और उसके तत्वों के बीच अंतर करने में विफल रहे हैं। आपको साझा करना चाहिए और को साझा-मेमोरी आईपीसी पर अपना हाथ देने से पहले अनुक्रमिक कोड में सरणी और पॉइंटर्स के साथ अधिक आरामदायक बनाना चाहिए।

ध्यान दें कि साझा स्मृति वहां आईपीसी करने के अधिक आसान-से-गलत तरीके से एक है। जब तक आपके पास कठोर दक्षता बाधा न हो और डेटा के बहुत सारे का आदान-प्रदान करने जा रहे हैं, तो पाइप, नामित पाइप या सॉकेट के साथ काम करना बहुत आसान है।

+0

धन्यवाद हेनिंग। – maddy

0

आपको डेटा का आदान-प्रदान करने के लिए पर्याप्त साझा स्मृति को आरक्षित करना चाहिए। साझा पॉइंटर्स का उपयोग करते हुए, प्रक्रियाओं को एक-दूसरे की स्मृति तक पहुंचने की आवश्यकता नहीं है। ध्यान रखें कि रनटाइम के दौरान आपके द्वारा लिखे गए कच्चे डेटा को साझा किया जाता है, कोई प्रकार की जांच या कोई अन्य मेटाडेटा पास नहीं होता है। डेटा को अधिक आसानी से एक्सेस करने के लिए, यदि आपका डेटा इसे निश्चित आकार के सरणी का उपयोग करने की अनुमति देता है, तो आप एक सामान्य संरचना का उपयोग कर सकते हैं। अन्यथा, आपको प्रक्रियाओं के बीच डेटा मैन्युअल रूप से मार्शल करना होगा।

11

अन्य दो उत्तरों ने आपको बताया कि क्या गलत है, लेकिन मैं आपको एक रननेबल कोड देना चाहता हूं। आप इसे कुछ भी पारित करने के लिए संशोधित कर सकते हैं, सिद्धांत यह है कि आपको दूसरी तरफ पारित हर तत्व की लंबाई को बचाने की आवश्यकता है।

//write.c

#include <stdio.h> 
#include <string.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 

int main() 
{ 
    key_t shm_key = 6166529; 
    const int shm_size = 1024; 

    int shm_id; 
    char* shmaddr, *ptr; 
    int next[2]; 

    printf ("writer started.\n"); 

    /* Allocate a shared memory segment. */ 
    shm_id = shmget (shm_key, shm_size, IPC_CREAT | S_IRUSR | S_IWUSR); 

    /* Attach the shared memory segment. */ 
    shmaddr = (char*) shmat (shm_id, 0, 0); 

    printf ("shared memory attached at address %p\n", shmaddr); 

    /* Start to write data. */ 
    ptr = shmaddr + sizeof (next); 
    next[0] = sprintf (ptr, "mandy") + 1; 
    ptr += next[0]; 
    next[1] = sprintf (ptr, "73453916") + 1; 
    ptr += next[1]; 
    sprintf (ptr, "amarica"); 
    memcpy(shmaddr, &next, sizeof (next)); 
    printf ("writer ended.\n"); 

    /*calling the other process*/ 
    system("./read"); 

    /* Detach the shared memory segment. */ 
    shmdt (shmaddr); 
    /* Deallocate the shared memory segment.*/ 
    shmctl (shm_id, IPC_RMID, 0); 

    return 0; 
} 

// पढ़ें।ग

#include <stdio.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 

int main() 
{ 
    key_t shm_key = 6166529; 
    const int shm_size = 1024; 

    int shm_id; 
    char* shmaddr, *ptr; 
    char* shared_memory[3]; 
    int *p; 

    /* Allocate a shared memory segment. */ 
    shm_id = shmget (shm_key, shm_size, IPC_CREAT | S_IRUSR | S_IWUSR); 

    /* Attach the shared memory segment. */ 
    shmaddr = (char*) shmat (shm_id, 0, 0); 

    printf ("shared memory attached at address %p\n", shmaddr); 

    /* Start to read data. */ 
    p = (int *)shmaddr; 
    ptr = shmaddr + sizeof (int) * 2; 
    shared_memory[0] = ptr; 
    ptr += *p++; 
    shared_memory[1] = ptr; 
    ptr += *p; 
    shared_memory[2] = ptr; 
    printf ("0=%s\n", shared_memory[0]); 
    printf ("1=%s\n", shared_memory[1]); 
    printf ("2=%s\n", shared_memory[2]); 

    /* Detach the shared memory segment. */ 
    shmdt (shmaddr); 
    return 0; 
} 

// रन के परिणाम:

> [lex:shm]$ ./write 
> writer started. 
> shared memory attached at address 0x7fa20103b000 
> writer ended. 
> shared memory attached at address0x7fd85e2eb000 
> 0=mandy 
> 1=73453916 
> 2=amarica 
+0

read.c के दौरान IPC_CREAT को कॉल नहीं करना चाहते हैं, मौजूदा को प्राप्त करने के बजाय साझा स्मृति का एक बिल्कुल नया सेट बनाएं? – Sherd