2011-08-30 57 views
12

Tôi đang cố gắng liên lạc giữa hai quy trình. Tôi đang cố lưu dữ liệu (như tên, số điện thoại, địa chỉ) vào bộ nhớ dùng chung trong một quy trình và cố gắng in dữ liệu đó qua quá trình khác.cách sử dụng bộ nhớ dùng chung để liên lạc giữa hai quy trình

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

Nhưng tôi không nhận được kết quả mong muốn. đầu ra mà tôi đã nhận là:

shared memory attached at address 0x7fff0fd2d460 
Segmentation fault 

Bất cứ ai cũng có thể vui lòng giúp tôi với điều này. Đây có phải là cách chính xác để khởi tạo shared_memory[3].

Cảm ơn bạn.

Trả lời

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

Bạn khai báo shared_memory như một mảng có khả năng giữ ba con trỏ đến char, nhưng những gì bạn thực sự làm gì với nó là viết một con trỏ một nơi đằng sau sự kết thúc của mảng. Vì không có gì nói cho bộ nhớ có gì khác được sử dụng cho, những gì xảy ra tiếp theo thường là không thể đoán trước.

Mọi thứ sẽ kết thúc xấu sau đó khi bạn cố gắng sử dụng các con trỏ trong shared_memory[0] qua shared_memory[2], vì những con trỏ đó chưa bao giờ được khởi tạo. Chúng được lấp đầy với rác vô nghĩa từ ngăn xếp - do đó lỗi phân đoạn.

Dường như, nói chung, bạn không phân biệt được giữa mảng và các phần tử của mảng. Bạn nên đi và làm cho mình nhiều hơn thoải mái hơn với mảng và con trỏ trong mã tuần tự trước khi bạn thử tay tại IPC chia sẻ bộ nhớ.

Lưu ý rằng bộ nhớ dùng chung là một trong những cách dễ dàng để thực hiện IPC ngoài kia. Trừ khi bạn có những hạn chế về hiệu quả cứng nhắc và sẽ trao đổi rất nhiều dữ liệu, dễ dàng hơn khi làm việc với các đường ống, ống có tên hoặc ổ cắm.

+0

Cảm ơn bạn Henning. – maddy

0

Bạn nên đặt đủ bộ nhớ dùng chung để trao đổi dữ liệu . Các quy trình không được phép truy cập vào bộ nhớ của người khác, ngay cả khi sử dụng các con trỏ được chia sẻ. Hãy nhớ chỉ dữ liệu thô bạn viết trong thời gian chạy được chia sẻ, không có kiểm tra loại hoặc bất kỳ siêu dữ liệu nào khác được chuyển. Bạn có thể sử dụng cấu trúc chung, nếu dữ liệu của bạn cho phép nó sử dụng mảng có kích thước cố định, để truy cập dữ liệu dễ dàng hơn. Nếu không, bạn sẽ phải tự điều chỉnh dữ liệu giữa các quy trình.

11

Hai câu trả lời khác cho bạn biết điều gì sai, nhưng tôi muốn cung cấp cho bạn một mã runnable. Bạn có thể sửa đổi nó để vượt qua bất cứ điều gì, nguyên tắc là bạn cần phải tiết kiệm chiều dài của mỗi phần tử bạn đã chuyển sang phía bên kia.

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

// đọc.c

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

// Kết quả chạy:

> [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

Sẽ không gọi IPC_CREAT trong read.c tạo một bộ bộ nhớ chia sẻ hoàn toàn mới thay vì nhận bộ nhớ hiện có? – Sherd

Các vấn đề liên quan