Общая память для чтения изменяемых массивов - PullRequest
0 голосов
/ 26 октября 2019

Я начинаю изучать основы ОС, и у меня нет никакого опыта в Си и указателях. Я делаю что-то не так в своем коде, но я не знаю, как это исправить. Я пытаюсь заполнить массив. Первый процесс инициализирует массив, а второй обновляет значения случайным образом. мои проблемы:

  1. первый процесс записывает в общую память, а затем завершается. Я хочу, чтобы он фактически прочитал массив после его обновления
  2. Я думаю, что я храню массив неправильноway
  3. Мне нужен способ сообщить каждому процессу, когда другой завершен, чтобы поддерживать связь, пока первый процесс не решит, что она закончена. ниже приведены мои коды:

Первый процесс


int main()

{
    key_t key; 
    int shm_id;
    int *shm_ptr;

    if ((key = ftok("/tmp", 'y')) == -1)  
    {   
        perror("ftok() failed");   
        exit(EXIT_FAILURE);
    }

    shm_id = shmget(key, SIZE*sizeof(int), IPC_CREAT | IPC_EXCL | 0600 );
    if (shm_id == -1)  
    {           
        perror("Failed to get memory");   
        exit(EXIT_FAILURE);
    }

    shm_ptr = (int *) shmat ( shm_id, NULL, 0);
    if (shm_ptr == (int *) -1)
    {
        perror( "shmat failed" ) ;
        exit( EXIT_FAILURE ) ;
    }

    printf("Array Initialized as : \n");

    for(int i=0; i<SIZE-1; i++)
    {
        shm_ptr[i]=-1;
    }
    // for(int i = 0; i< 30; i++)
    // {
    //  printf(" %d", shm_ptr[i]);
    // }

    shmdt(shm_ptr);

    // shmctl(shm_id,IPC_RMID, NULL);

    return 0;
}

Второй процесс

int main()

{
    key_t key;
    int sum = 0;
    int shm_id;
    int *shm_ptr;

    key = ftok("/tmp", 'y');

    shm_id = shmget( key, 0 , 0600 );
    if (shm_id == -1)  
    {
        perror("Failed to get memory");   
        exit(EXIT_FAILURE);
    }
    shm_ptr = (int*) shmat(shm_id,NULL,0);

    printf("Client array \n");
    srand(time(NULL));
    for(int i = 0; i< 30; i++)
    {
        shm_ptr[i] = rand() % 20 + 1;
    }
    for(int i = 0; i< 30; i++)
    {
        printf(" %d", shm_ptr[i]);  
    }
    shmdt(shm_ptr);

    shmctl(shm_id,IPC_RMID, NULL);

    return 0;

}

1 Ответ

0 голосов
/ 27 октября 2019

В вашей программе отсутствует синхронизация процессов. По сути, ваш второй процесс может попытаться получить сегмент общей памяти, который не существует в данный момент. Поскольку вы работаете с двумя исполняемыми файлами, приобретение PID не является опцией, следовательно, мы не можем использовать сигналы. Но мы можем заставить его работать только с сегментами разделяемой памяти.

Создайте дополнительный сегмент совместно используемой памяти, такой как data_ready. Вы хотите использовать IPC_CREAT на обоих, но не IPC_EXCL . И пусть ваш первый процесс установит его на единицу после инициализации массива. Поскольку мы использовали IPC_CREAT , ни один из процессов не будет перезаписывать данные, если процесс не существует и, если он не существует, первый процесс в любом случае инициализирует его как 0. Вы можете вфакт, удалите IPC_EXCL в вашем первом процессе, если вы используете это.

Сделайте так, чтобы ваш первый процесс установил data_ready в 1, как только он инициализировал массив, и заблокируйте ваш второй процесс, используя команду, такую ​​как `` `while (data_ready == 0);` `` `

Это довольно грубый метод для этого. Конечно, вы можете сделать это намного лучше с потоками, семафорами, очередями сообщений и т. Д. Но в настоящее время это должно сделать работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...