2015-05-19 2 views
0

Я написал две программы (программа 1 и программа 2) для связи друг с другом с использованием общей памяти. программа 1 считывает из файла предложение и передает его после модификации, чтобы получить первую букву каждого слова и ее размер для следующей программы (программа 2). Я столкнулся с проблемой состояния гонки. Я добавил алгоритм Петерсона, но как только я выполнил 2 программы на переднем плане, а один в фоновом режиме, я не получил никакого результата.C++ пытается добавить алгоритм Петерсона, чтобы избежать состояния гонки в общей памяти

-once я удалить алгоритм Петерсона мои программы работают

работает в -Я Linux с использованием C++

программы 1

#include<iostream> 
#include<fstream> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <sys/types.h> 
#include <stdlib.h> 
#include <unistd.h> 

using namespace std; 

int filesize(){ 

ifstream input; 
input.open("file1.txt"); 

string temp; 

int i = 0; 

while(input>>temp){i++;} 

input.close(); 

return i; 
} 

struct shdata 
{ 
char c;  
    int n; 
    int size; 
    bool flag[2]; 
    int turn; 
}; 

int main(){ 
ifstream input; 
    input.open("file1.txt"); 

int shmid; 
key_t key = 8006; 

struct shdata *shm; 



shmid = shmget(key, sizeof(struct shdata), IPC_CREAT | 0666); 

if(shmid < 0){ 
    cout<<"Error .. Can not get memory\n"; 
    exit(0); 
} 

    shm = (struct shdata *)shmat (shmid, NULL, 0); 

    if(shm <= (struct shdata *)(0)) 
    { 
     cout<<"Errors.. Can not attach\n"; 
     exit(1); 
    } 
    shm->flag[0]=false; 
    shm->flag[1]=true; 
    string temp; 


    while(input>>temp){ 
    shm->flag[0]=true; 
    shm->turn = 1;   
    while(shm->flag[1]== true && shm-> turn == 1); 

    shm->c=temp[0]; 
    shm->n=temp.size(); 
    shm->size = filesize(); 


    shm->flag[0]=false; 
    sleep(1); 
    } 


return 0; 
} 

программа 2

#include<iostream> 
    #include<fstream> 
    #include <sys/ipc.h> 
    #include <sys/shm.h> 
    #include <sys/types.h> 
    #include <stdlib.h> 
    #include <unistd.h> 

    using namespace std; 

    int filesize(){ 

ifstream input; 
input.open("file1.txt"); 

string temp; 

int i = 0; 

while(input>>temp){i++;} 

input.close(); 

return i; 
    } 

    struct shdata 
    { 
char c;  
    int n; 
    int size; 
    bool flag[2]; 
    int turn; 
    }; 

    int main(){ 

int shmid; 
key_t key = 8006; 

struct shdata *shm; 



    shmid = shmget(key, sizeof(struct shdata), 0); 
if(shmid < 0) 
    { 
    cout<<"Error .. Can not get memory\n"; 
    exit(0); 
    } 

    shm = (struct shdata *)shmat (shmid,0, 0); 

    if(shm <= (struct shdata *)(0)) 
    { 
    cout<<"Error .. Can not attach\n"; 
    exit(1); 
    } 
    int c =0; 
    while(c<shm->size){ 

shm->flag[1] = true; 
    shm->turn=0; 

while(shm->flag[0]==false && shm->turn == 0); 

sleep(1);  
for(int i = 0; i < shm->n ;i++) 
{ 
    cout<<shm->c; 
} 
cout<<endl; 

shm->flag[1]=false; 

c++; 
} 
shmctl(shmid, IPC_RMID, NULL); 

return 0; 
}   
+0

Правильное форматирование кода сделает его намного более легким для чтения, понимания и отладки. –

+0

Это может быть связано с трудностями вставки кода в формы SO. –

+1

Руководство по размещению кода: http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks –

ответ

2

программа 2 никогда не попадает в петлю while(c<shm->size), потому что в этот момент shm->size - 0. Чтобы обойти это, програн 1 должен инициализировать shm->size, прежде чем программа 2 дойдет до этой точки. Это может привести к другому состоянию гонки, потому что, похоже, нет механизма для обеспечения того, чтобы разделяемая память была инициализирована программой 1, прежде чем программа 2 начнет ее использовать.

Кажется, что это работает без алгоритма Петерсона, потому что в этом случае программа 1 не ждет флаг и инициализирует shm->size дальше в цикле.

0

Вы используете член flag, чтобы синхронизировать вас с 2 программами, но эта работа не работает, потому что вы не можете следовать последовательности чтения/записи. Вы должны использовать небольшой диалект, чтобы ваши две программы запускались в правильном порядке.

+0

спасибо, но что вы говорите по диалекту –

+0

вместо булевых значений, вы можете использовать перечисление типа 'enum {idle, running, waiting}'. Затем замените spin-wait 'while (...);' s. Цель состоит в следующем: p2 должен ждать p1 находится в правильном состоянии перед запуском, а p1 должен ждать p2, чтобы использовать данные перед обработкой следующего элемента. – norisknofun

Смежные вопросы