简体   繁体   English

在2个进程之间使用命名管道连续通信

[英]continuously communicate using named pipes between 2 processes

I've written this code which has 2 different processes in 2 different programs(present in same folder) that operates on a single named pipe. 我已经编写了这段代码,该代码在一个命名管道上运行的2个不同程序(存在于同一文件夹中)中具有2个不同的进程。 1st program has a pointer that continuously passes thru the list. 第一个程序具有一个不断通过列表的指针。 When the 'timer interrupt' is received from my another program (timer.c), the pointer has to stop and that particular list is removed. 当从另一个程序(timer.c)收到“定时器中断”时,指针必须停止并且该特定列表被删除。

These are my 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);
}

The problem is my 1st prog is not able to catch the timer properly. 问题是我的第一个编不能正确捕获计时器。 My timer program also never receives the "stop" that 1st prog sends. 我的计时器程序也永远不会收到第一个编发送的“停止”消息。 Hence there is no sync at all. 因此根本没有同步。 Sometimes, after more than 2 'interrupts' received from timer, the 1st prog catches and removes the node. 有时,在从计时器接收到2个以上的“中断”后,第一个分支会捕获并删除该节点。

What am I missing here?? 我在这里想念什么?

If you're using Linux, named pipes (fifos) and also unnamed pipes (shell "|") are one-way only. 如果您使用的是Linux,则命名管道(fifos)和未命名管道(shell“ |”)都是单向的。 If you need bidirectional communication, you need either a second named pipe, or changing to another communication tool such as a socketpair. 如果需要双向通信,则需要第二个命名管道,或更改为另一个通信工具,例如套接字对。

Also, when using pipes, it might be good to open them in blocking mode. 同样,在使用管道时,最好以阻塞模式打开它们。 That will ensure that both programs (client and server) go beyond the open() call only when both have engaged to the pipe. 这将确保两个程序(客户端和服务器)仅在两者都已参与管道时才超出open()调用。 Otherwise, if the writer connects before the reader, some data might be lost (I'm not completely sure about this). 否则,如果作者在读者之前连接,则可能会丢失一些数据(对此我不太确定)。

These links might be useful to know more about fifos and sockerpairs: 这些链接可能有助于了解fifos和sockerpairs:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM