2016-06-30 3 views
0

Я написал этот код, который имеет 2 разных процесса в двух разных программах (присутствует в одной папке), который работает на одном и том же канале. 1-я программа имеет указатель, который непрерывно проходит через список. Когда «прерывание таймера» получено из моей другой программы (timer.c), указатель должен остановиться, и этот конкретный список будет удален.непрерывно связывается с использованием именованных каналов между двумя процессами

Это мой код:

ball.c

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <limits.h> 
#include <string.h> 
#include <unistd.h> 

#define FIFO_NAME "my_fifo" /* the fifo name */ 

#define BUFFER_SIZE 10 


struct node 
{ 
int data; 
struct node* next; 
}; 


struct node* create_new() 
{ 
struct node* temp = (struct node *)malloc(sizeof(struct node)*1); 
return temp; 
}; 


void populate_list(struct node **head, int players) 
{ 
struct node *current, *temp; 
int i = 1; 
temp = create_new(); 
temp->data = i++; 
temp->next = temp; 
*head = temp; 
while(i <= players){ 
    current = create_new(); 
    current->data = i; 
    current->next = *head; 
    temp->next = current; 
    temp = current; 
    i++; 
} 
} 


void display_list(struct node **head) 
{ 
if(NULL == *head) 
{ 
    printf("the list is empty\n"); 
} 
else 
{ 
    struct node *temp = *head; 
    while(temp->next != *head){ 
     printf("%d - ", temp->data); 
     temp = temp->next; 
    } 
    printf("%d\n", temp->data); 
} 
} 


void delete_player(struct node **pos) 
{ 
printf("Deleting Player - '%d'\n", (*pos)->data); 
struct node *temp, *ptr; 
temp = ptr = *pos; 
while(temp->next != *pos){ 
    temp = temp->next; 
} 
temp->next = ptr->next; 
free(ptr); 
*pos = temp; 
} 



int main(int argc, char **argv) 
{ 
int res; 
char buffer[BUFFER_SIZE + 1]; 
if (access(FIFO_NAME, F_OK) == -1)  /* check if fifo already exists*/ 
{ 
    res = mkfifo(FIFO_NAME, 0777); /* if not then, create the fifo*/ 
    if (res != 0) { 
     fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME); 
     exit(EXIT_FAILURE); 
    } 
} 

memset(buffer, '\0', BUFFER_SIZE+1);  /* clear the string */ 

printf("Process %d - opening FIFO\n\n", getpid()); 
res = open(FIFO_NAME, O_RDWR | O_NONBLOCK); 

struct node *head = NULL; 
int players; 

printf("Enter the number of players: "); 
scanf("%d", &players); 

populate_list(&head, players); 
printf("\nThe players are: \n"); 
display_list(&head); 

printf("\n-------------------Game Started-----------------\n"); 

struct node *pos, *start = head; 
int breakflag = 0; 

while(start->next != start) 
{ 
    while(breakflag == 0) 
    { 
     read(res, buffer, BUFFER_SIZE+1); 
     if(strcmp(buffer, "intr") == 0){ 
      breakflag = 1; 
      memset(buffer, '\0', BUFFER_SIZE+1); 
     } 
     start = start->next; 
    } 
    pos = start; 
    start = start->next; 
    printf("\nThe ball is currently with Player '%d'\n", pos->data); 
    delete_player(&pos); 
    display_list(&pos); 
    breakflag = 0;  //Restart the passing game 
} 

printf("\nWinner: Player '%d'\n", start->data); 
free(start); 

write(res, "stop", strlen("stop")+1); 

if(res != -1) 
    (void)close(res); /* close the fifo */ 

printf("Process %d - ballpass.c - finished\n", getpid()); 

return 0; 
} 

timer.c

#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <limits.h> 

#define FIFO_NAME "my_fifo" /* the fifo name */ 
#define FIFO_NAME1 "my_fifo1" /* the fifo name */ 
#define BUFFER_SIZE 10 

/* Used to generate the timer delay */ 
void waitFor(unsigned int secs) 
{ 
unsigned int retTime = time(0) + secs; 
while(time(0) < retTime); 
} 

int main() 
{ 
int res, i, random_time; 
char buffer[BUFFER_SIZE + 1]; 

if (access(FIFO_NAME, F_OK) == -1) { /* check if fifo already exists*/ 
    res = mkfifo(FIFO_NAME, 0777); /* if not then, create the fifo*/ 
    if (res != 0) { 
     fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME); 
     exit(EXIT_FAILURE); 
    } 
} 

memset(buffer, '\0', BUFFER_SIZE+1); /* clear the string */ 

printf("Process %d - opening FIFO\n\n", getpid()); 
res = open(FIFO_NAME, O_RDWR | O_NONBLOCK); 

while(1) 
{ 
    read(res, buffer, BUFFER_SIZE+1); 
    if(strcmp(buffer, "stop") == 0) 
     break; 

    random_time = rand()%10; 
    waitFor(random_time); 

    write(res, "intr", strlen("intr")+1); 

    printf("Process %d - Timer sent interrupt\n"); 
} 

if (res != -1) 
    (void)close(res); /* close the fifo */ 

printf("Process %d - timer.c - finished\n", getpid()); 

exit(EXIT_SUCCESS); 
} 

Проблема моя первая прога не в состоянии поймать таймер должным образом. Моя программа таймера также никогда не получает «остановку», которую отправляет 1-я прога. Следовательно, синхронизации вообще нет. Иногда после получения более 2 «прерываний», полученных от таймера, 1-я прог улавливает и удаляет узел.

Что мне здесь не хватает?

ответ

1

Если вы используете Linux, именованные каналы (fifos), а также неназванные каналы (оболочка «|») являются однонаправленными. Если вам нужна двунаправленная связь, вам нужен либо второй именованный канал, либо переход на другой инструмент связи, такой как socketpair.

Кроме того, при использовании труб может быть полезно открыть их в режиме блокировки. Это гарантирует, что обе программы (клиент и сервер) выходят за вызов open() только тогда, когда оба они подключены к трубе. В противном случае, если писатель подключится к считывателю, некоторые данные могут быть потеряны (я не совсем уверен в этом).

Эти ссылки могут быть полезными, чтобы узнать больше о FIFOs и sockerpairs: