2016-06-30 45 views
0

我已經編寫了這個代碼,它在2個不同的程序(存在於同一個文件夾中)中具有2個不同的進程,該程序在單個命名管道上運行。 第一個程序有一個連續通過列表的指針。當從另一個程序(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); 
} 

問題是我的第一個前衛無法趕上計時器正常。我的定時器程序也從來沒有收到第一個編髮送的「停止」。因此根本沒有同步。 有時,在從定時器收到2個'中斷'之後,第1個prog會捕獲並刪除該節點。

我在這裏錯過了什麼?

回答

1

如果您使用的是Linux,命名管道(fifos)和未命名管道(shell「|」)僅是單向的。如果您需要雙向通信,則需要第二個命名管道,或更改爲其他通信工具(如套接字對)。

另外,使用管道時,最好在阻塞模式下打開它們。這將確保兩個程序(客戶端和服務器)只有在兩者都與管道連接時才超出open()調用。否則,如果作者在讀者之前連接,一些數據可能會丟失(我對此不完全確定)。

這些鏈接可能會更多地瞭解FIFO和sockerpairs有用:

相關問題