• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Komunikacja poprzez pamięc dzieloną na Linux, język C

+1 głos
683 wizyt
pytanie zadane 28 listopada 2016 w C i C++ przez BloodyNomad Początkujący (310 p.)

Cześć. Mam program do komunikacji międzyprocesowej, tworzący segment pamięci dzielonej pozwalający zapisywać i odczytywać komunikaty.

Mam problem z dodaniem opcji żeby moje komunikaty zapisywały się w tablicy w segmencie pamięci dzielonej w taki sposób:

- zapisz k "komunikat" - zapisz komunikat w wierszu k tablicy stringów w pamięci dzielonej,
- odczytaj k - odczytaj komunikat z wiersza k tablicy w pamięci dzielonej.

 

Jak to zrobić?

 

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>

#define SEGSIZE 100

main( int argc, char * argv[] )
{
    int shmid, cntr;
    char * segptr;
   
    /* Jeśli nie wpisano parametru przejdź do usage() */
    if( argc == 1 )
         usage();
   
    /* utwórz unikalny klucz poprzez wywołanie ftok() */
    key_t key;
    key = ftok( ".", 'S' );
   
    /* otwórz segment pamięci dzielonej - utwórz jeżeli trzeba; nadanie praw do segmentu */
    if(( shmid = shmget( key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666 ) ) == - 1 )
    {
        printf( "Segment pamięci dzielonej istnieje - otwieram jako klient\n" );
       
        /* Segment prawdopodobnie istnieje - próbuję otworzyć jako klient */
        if(( shmid = shmget( key, SEGSIZE, 0 ) ) == - 1 )
        {
            perror( "shmget" );
            exit( 1 );
        }
    }
    else
    {
        printf( "Tworzenie nowego segmentu pamięci dzielonej\n" );
    }
   
    /* Podłącz segment pamięci dzielonej do tego procesu */
    if(( segptr = shmat( shmid, 0, 0 ) ) == - 1 )
    {
        perror( "shmat" );
        exit( 1 );
    }
    /* Wybór funkcji zapisu/odczytu ze zmianą dużej litery na małą */
    switch( tolower( argv[ 1 ][ 0 ] ) )
    {
    case 'z': writeshm( shmid, segptr, argv[ 2 ] );
        break;
    case 'o': readshm( shmid, segptr );
        break;
        /* Jeśli wybrano zły parametr przechodzi do usage() */
        default: usage();
       
    }
}
/* Zapisuje w pamięci wpisany text */
writeshm( int shmid, char * segptr, char * text )
{
    strcpy( segptr, text );
    printf( "Zrobiono...\n" );
}
/* Zwraca na stdout wartości zapisane w pamięci */
readshm( int shmid, char * segptr )
{
    printf( "segptr: %s\n", segptr );
}

/* Wyświetla schemat prawidłowego wywołania programu */
usage()
{
    fprintf( stderr, "Program do komunikacji międzyprocesowej\n" );
    fprintf( stderr, "\nPOSTAĆ WYWOŁANIA:  <nazwa programu> (z)apisz <text>\n" );
    fprintf( stderr, "     (o)dczytaj\n" );
   
    exit( 1 );
}

 

1 odpowiedź

0 głosów
odpowiedź 30 listopada 2016 przez BloodyNomad Początkujący (310 p.)

Zacząłem kombinować z dzieleniem segmentu, ale zwraca błąd.

http://pastebin.com/tHGhrvqy

 

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>
 
#define SEGSIZE 1000
#define NUMSEGS 20
 
 
 
int main( int argc, char * argv[] )
{
    int shmid;
   char *segptr[NUMSEGS];
int k = argv [ 2 ];
 
    /* Jeśli nie wpisano parametru przejdź do usage() */
    if( argc == 1 )
         usage();
   
    /* utwórz unikalny klucz poprzez wywołanie ftok() */
    key_t key;
    key = ftok( ".", 'S' );
   
    /* otwórz segment pamięci dzielonej - utwórz jeżeli trzeba; nadanie praw do segmentu */
    if(( shmid = shmget( key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666 ) ) == - 1 )
    {
        printf( "Segment pamięci dzielonej istnieje - otwieram jako klient\n" );
       
        /* Segment prawdopodobnie istnieje - próbuję otworzyć jako klient */
        if(( shmid = shmget( key, SEGSIZE, 0 ) ) == - 1 )
        {
            perror( "shmget" );
            exit( 1 );
        }
    }
    else
    {
        printf( "Tworzenie nowego segmentu pamięci dzielonej\n" );
    }
   
    /* Podłącz segment pamięci dzielonej do tego procesu */
    if(( segptr[NUMSEGS] = shmat( shmid, 0, 0 ) ) == - 1 )
    {
        perror( "shmat" );
        exit( 1 );
    }
 
    /* Wybór funkcji zapisu/odczytu ze zmianą dużej litery na małą */
 
    switch( tolower( argv[ 1 ][ 0 ] ) )
    {
   
    case 'z':
        strcpy( segptr[k], argv[ 3 ] );
        printf( "Zrobiono... \n");
        break;
   
 
    case 'o':
        printf( "segptr: %s\n", segptr[k] );
    break;
       
    /* Jeśli wybrano zły parametr przechodzi do usage() */
        default: usage();
       
    }
}
 
/* Wyświetla schemat prawidłowego wywołania programu */
usage()
{
    fprintf( stderr, "Program do komunikacji międzyprocesowej\n" );
    fprintf( stderr, "\nPOSTAĆ WYWOŁANIA:  <nazwa programu> (z)apisz <text>\n" );
    fprintf( stderr, "                  (o)dczytaj\n" );
   
    exit( 1 );
}

 

Podobne pytania

0 głosów
1 odpowiedź 732 wizyt
pytanie zadane 1 lipca 2019 w Rozwój zawodowy, nauka, praca przez gorgonkowa Obywatel (1,810 p.)
0 głosów
1 odpowiedź 654 wizyt
pytanie zadane 2 listopada 2019 w Sprzęt komputerowy przez Robert :) Nowicjusz (120 p.)
0 głosów
5 odpowiedzi 1,269 wizyt
pytanie zadane 17 kwietnia 2016 w C i C++ przez Azholi Początkujący (260 p.)

93,776 zapytań

142,736 odpowiedzi

323,388 komentarzy

63,381 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...