2016-06-30 13 views
0

Ich habe diesen Code geschrieben, der 2 verschiedene Prozesse in 2 verschiedenen Programmen (vorhanden in demselben Ordner) hat, die auf einer einzigen Named Pipe arbeitet. 1. Programm hat einen Zeiger, der kontinuierlich durch die Liste geht. Wenn der "Timer-Interrupt" von meinem anderen Programm (timer.c) empfangen wird, muss der Zeiger stoppen und diese bestimmte Liste wird entfernt. kommunizieren kontinuierlich mit Named Pipes zwischen 2 Prozessen

Das sind meine Code:

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

Das Problem ist meine erste prog nicht in der Lage ist, den Timer zu fangen richtig. Mein Timer-Programm erhält auch nie den "Stop", den das 1. Prog sendet. Daher gibt es überhaupt keine Synchronisierung. Manchmal, nachdem mehr als 2 'Interrupts' vom Timer empfangen wurden, fängt das 1. prog den Knoten ab und entfernt ihn.

Was fehlt mir hier ??

Antwort

1

Wenn Sie Linux verwenden, sind Named Pipes (Fifos) und auch unbenannte Pipes (Shell "|") nur in einer Richtung. Wenn Sie bidirektionale Kommunikation benötigen, benötigen Sie entweder eine zweitgenannte Pipe oder wechseln zu einem anderen Kommunikationstool wie einem Sockelpaar.

Auch bei der Verwendung von Rohren kann es hilfreich sein, sie im Sperrmodus zu öffnen. Dadurch wird sichergestellt, dass beide Programme (Client und Server) nur dann über den Aufruf von open() hinausgehen, wenn beide mit der Pipe verbunden sind. Andernfalls, wenn der Schreiber vor dem Leser eine Verbindung herstellt, können einige Daten verloren gehen (ich bin mir da nicht ganz sicher).

könnten diese Links nützlich sein, um mehr über fifos und sockerpairs zu wissen: