c - While 循环中的 FIFO 卡住并等待读取

标签 c unix fork ipc fifo

服务器将其 PID 发送到客户端,客户端在循环中获取并发送 SIGUSR1 信号,因此我在服务器代码中有处理程序。从理论上讲,它需要获取信号并为客户端创建一些随机矩阵。客户端接收服务器 PID 但由于某种原因它从不向客户端发送矩阵。它等待并永远插入闪烁。我假设它们以某种方式不相互连接,但为什么呢?我尝试发送一个矩阵,结果很好。

客户端.c

int main()
{
    int n=2;
      pid_t pid=1;
      int i,j;
      double matrix[20][20];
   char *myfifo2 = "/tmp/kek_fifo";
       int server_to_client;
   char *myfifo3 = "/tmp/fifor_fifo";
       int fifor;
       int forke=1;

   char str[BUFSIZ];
     fifor = open(myfifo3, O_RDONLY);
        read(fifor,&pid,sizeof(pid));
        printf("pid %d\n",pid);

   close(fifor);
    unlink(myfifo3);



 while(1){
      printf("no\n");
      server_to_client = open(myfifo2, O_RDONLY);
      read(server_to_client,matrix,sizeof(matrix));
      close(server_to_client);
      printf("yes\n");
    forke=fork();
    if(forke){

        printf("forke buyuktur >= parent olmali %d \n",forke);
     for(i = 0; i < 2*n; i++){
        for(j = 0; j < 2*n; j++){
            printf("%2f ",matrix[i][j]);
        }
        printf("\n");
    }
        wait(0); //parent child bekliyo 
    }

    else{
        printf("forke =0  yani child %d \n",forke);

        exit(0);
    }
        //sleep(5);
       kill(pid,SIGUSR1);


    }   


   return 0;
}

服务器.c

void actionHandler(int signum);
void matrix_init(double m[20][20],int n);
void randome(double myPointer[20][20],int n);

static int signalcheck=0;
int main()
{
   int i,j;
      int n=2; //argv olacak
      pid_t pide=getpid();
      printf("pide is %d \n",pide);
       struct sigaction action;
       action.sa_handler=actionHandler; 
       action.sa_flags = 0;

   int client_to_server;
   char *myfifo = "/tmp/client_to_server_fifo";
   int forke;
   int server_to_client;
   char *myfifo2 = "/tmp/kek_fifo";
   char *myfifo3 = "/tmp/fifor_fifo";
   int fifor;
   char buf[BUFSIZ];
   double M[20][20];
    matrix_init(M,n);

   /* create the FIFO (named pipe) */
 //  mkfifo(myfifo, 0666);
  mkfifo(myfifo2, 0666);
   mkfifo(myfifo3,0666);

   fifor =open(myfifo3,O_WRONLY);
   write(fifor,&pide,sizeof(pide));
   close(fifor);
   unlink(myfifo3);

   if ((sigemptyset(&action.sa_mask) == -1) ||
      (sigaction(SIGUSR1, &action, NULL) == -1))
      perror("Failed to install SIGURS1 signal handler");

   /* open, read, and display the message from the FIFO */
  // client_to_server = open(myfifo, O_RDONLY);


   printf("Server ON.\n");

   while (1)
   {



   if(signalcheck==1){

   forke=fork();
   if(forke==0){
      while(1){
         randome(M,n);

         server_to_client = open(myfifo2, O_WRONLY);
         write(server_to_client,M,sizeof(M));
         close(server_to_client);
         unlink(myfifo2);
         printf("matrix yarat\n");
         //sleep(5);
         //create matrix send to fifo 
      }
   }
      /*
      read(client_to_server, buf, BUFSIZ);

      if (strcmp("exit",buf)==0)
      {
         printf("Server OFF.\n");
         break;
      }

      else if (strcmp("",buf)!=0)
      {
         printf("Received: %s\n", buf);
         printf("Sending back...\n");
         write(server_to_client,buf,BUFSIZ);
      }

       clean buf from any data 
      memset(buf, 0, sizeof(buf)); */
         //sleep(5);
   }
   signalcheck=0;
   }

 //  close(client_to_server);
 //  close(server_to_client);
// unlink(myfifo);
  // unlink(myfifo2);
   return 0;
}
 void actionHandler(int signum)
{
    signalcheck=1;
      if(signum==SIGUSR1)
         printf("i catched signal code from client  i guess \n");
    /* Signal handler code goes here. */

}


void matrix_init(double m[20][20],int z){
    /* 
    this function purpose to create
    2Nx2N int matrix n being int z
    then initing this matrix to 0 before random numbers take in part
    it has error checks .
    blah!*/
    int i, j,n=z;
    double **k = (double **) malloc(n * sizeof(double*));

    if(m == NULL){
        printf("Error full matrix not created");
        exit(-1);
    }

    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            m[i][j] = 0;
        }
    }

}


 void randome(double  myPointer[20][20],int n){
    int i,j;
    int r;
    srand ( time(NULL) );
    for(i=0;i<n*2;i++)
        for(j=0;j<n*2;j++)
            myPointer[i][j]=rand()%10;
 }

最佳答案

我认为您的问题被忽视这么久的一个原因是代码中有相当多的代码和相当多的评论是不相关的代码,而且布局并不整洁。这些加起来就是“阅读代码是一项艰苦的工作”,这让人们无法真正阅读代码。

此代码似乎在运行 macOS Sierra 10.12.4 的 MacBook Pro 上使用 GCC 6.3.0 进行编译时运行正常。

客户端代码

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    int n = 2;
    pid_t pid = 1;
    int i, j;
    double matrix[20][20];
    char *myfifo2 = "/tmp/kek_fifo";
    int server_to_client;
    char *myfifo3 = "/tmp/fifor_fifo";
    int fifor;
    int forke = 1;

    fifor = open(myfifo3, O_RDONLY);
    read(fifor, &pid, sizeof(pid));
    printf("pid %d\n", pid);

    close(fifor);
    unlink(myfifo3);

    for (int loopnum = 0; loopnum < 20; loopnum++)
    {
        printf("begin loop %d\n", loopnum);
        kill(pid, SIGUSR1);
        printf("signal sent\n");
        server_to_client = open(myfifo2, O_RDONLY);
        printf("Open done\n");
        read(server_to_client, matrix, sizeof(matrix));
        printf("read done\n");
        close(server_to_client);
        printf("close done\n");
        forke = fork();
        if (forke)
        {
            printf("forke buyuktur >= parent olmali %d\n", forke);
            for (i = 0; i < 2 * n; i++)
            {
                for (j = 0; j < 2 * n; j++)
                {
                    printf("%2f ", matrix[i][j]);
                }
                printf("\n");
            }
            wait(0); // parent child bekliyo
        }
        else
        {
            printf("forke = 0  yani child %d\n", forke);
            exit(loopnum);
        }
    }

    return 0;
}

服务器代码

#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

void actionHandler(int signum);
void matrix_init(double m[20][20], int n);
void randome(double myPointer[20][20], int n);

static volatile sig_atomic_t signalcheck = 0;

int main(void)
{
    int n = 2; // argv olacak
    pid_t pide = getpid();
    printf("pide is %d\n", pide);
    struct sigaction action;
    action.sa_handler = actionHandler;
    action.sa_flags = 0;

    int forke;
    int server_to_client;
    char *myfifo2 = "/tmp/kek_fifo";
    char *myfifo3 = "/tmp/fifor_fifo";
    int fifor;
    double M[20][20];
    matrix_init(M, n);
    srand(time(NULL));

    if ((sigemptyset(&action.sa_mask) == -1) ||
        (sigaction(SIGUSR1, &action, NULL) == -1))
    {
        perror("Failed to install SIGURS1 signal handler");
        return 1;
    }

    /* create the FIFO (named pipe) */
    mkfifo(myfifo2, 0666);
    mkfifo(myfifo3, 0666);

    fifor = open(myfifo3, O_WRONLY);
    write(fifor, &pide, sizeof(pide));
    close(fifor);
    unlink(myfifo3);

    printf("Server ON (%d).\n", signalcheck);

    while (1)
    {
        if (signalcheck == 1)
        {
            printf("Signal received:\n");
            signalcheck = 0;
            randome(M, n);
            forke = fork();
            if (forke == 0)
            {
                    server_to_client = open(myfifo2, O_WRONLY);
                    write(server_to_client, M, sizeof(M));
                    close(server_to_client);
                    printf("matrix yarat %d\n", (int)getpid());
                    exit(0);
            }
            else
            {
                int corpse;
                int status;
                while ((corpse = wait(&status)) != -1)
                    printf("PID %d exited with status 0x%.4x\n", corpse, status);
            }
        }
    }

    return 0;
}

void actionHandler(int signum)
{
    static char msg[] = "I caught a signal from the client\n";
    signalcheck = 1;
    if (signum == SIGUSR1)
    {
        int nb = write(1, msg, sizeof(msg)-1);
        assert(nb == sizeof(msg)-1);
    }
}

void matrix_init(double m[20][20], int z)
{
    for (int i = 0; i < z; i++)
    {
        for (int j = 0; j < z; j++)
            m[i][j] = 0;
    }
}

void randome(double myPointer[20][20], int n)
{
    int i, j;
    for (i = 0; i < n * 2; i++)
    {
        for (j = 0; j < n * 2; j++)
            myPointer[i][j] = rand() % 10;
    }
}

服务器输出

pide is 474
Server ON (0).
I caught a signal from the client
Signal received:
matrix yarat 476
PID 476 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 478
PID 478 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 481
PID 481 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 483
PID 483 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 485
PID 485 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 488
PID 488 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 491
PID 491 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 493
PID 493 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 496
PID 496 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 499
PID 499 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 501
PID 501 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 503
PID 503 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 506
PID 506 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 512
PID 512 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 514
PID 514 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 516
PID 516 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 518
PID 518 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 521
PID 521 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 523
PID 523 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 525
PID 525 exited with status 0x0000
^C

^C 是我在终端窗口中中断服务器的地方。该程序在一个繁忙的循环中旋转,使用了 99.5% 的 CPU。

客户端输出

pid 474
begin loop 0
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 477
5.000000 6.000000 0.000000 9.000000 
2.000000 1.000000 4.000000 7.000000 
0.000000 8.000000 2.000000 5.000000 
7.000000 8.000000 3.000000 2.000000 
forke = 0  yani child 0
begin loop 1
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 480
0.000000 7.000000 0.000000 3.000000 
0.000000 7.000000 2.000000 9.000000 
2.000000 4.000000 5.000000 5.000000 
9.000000 7.000000 3.000000 4.000000 
forke = 0  yani child 0
begin loop 2
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 482
8.000000 6.000000 1.000000 4.000000 
9.000000 2.000000 3.000000 9.000000 
2.000000 3.000000 8.000000 0.000000 
7.000000 8.000000 9.000000 8.000000 
forke = 0  yani child 0
begin loop 3
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 484
1.000000 4.000000 2.000000 9.000000 
5.000000 3.000000 5.000000 0.000000 
5.000000 9.000000 7.000000 5.000000 
3.000000 1.000000 7.000000 3.000000 
forke = 0  yani child 0
begin loop 4
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 487
2.000000 3.000000 0.000000 4.000000 
0.000000 2.000000 6.000000 8.000000 
1.000000 8.000000 8.000000 7.000000 
7.000000 4.000000 1.000000 4.000000 
forke = 0  yani child 0
begin loop 5
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 489
6.000000 3.000000 4.000000 0.000000 
5.000000 9.000000 2.000000 3.000000 
9.000000 7.000000 5.000000 4.000000 
5.000000 9.000000 1.000000 8.000000 
forke = 0  yani child 0
begin loop 6
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 492
7.000000 1.000000 4.000000 6.000000 
7.000000 1.000000 2.000000 4.000000 
5.000000 1.000000 8.000000 6.000000 
1.000000 9.000000 8.000000 6.000000 
forke = 0  yani child 0
begin loop 7
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 495
0.000000 0.000000 5.000000 1.000000 
6.000000 8.000000 3.000000 1.000000 
8.000000 1.000000 6.000000 9.000000 
7.000000 3.000000 1.000000 5.000000 
forke = 0  yani child 0
begin loop 8
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 497
3.000000 0.000000 1.000000 8.000000 
4.000000 4.000000 2.000000 3.000000 
8.000000 9.000000 6.000000 3.000000 
1.000000 3.000000 6.000000 3.000000 
forke = 0  yani child 0
begin loop 9
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 500
4.000000 0.000000 9.000000 3.000000 
1.000000 5.000000 1.000000 2.000000 
3.000000 0.000000 5.000000 6.000000 
4.000000 5.000000 9.000000 7.000000 
forke = 0  yani child 0
begin loop 10
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 502
4.000000 9.000000 7.000000 6.000000 
6.000000 4.000000 7.000000 1.000000 
3.000000 5.000000 9.000000 0.000000 
7.000000 9.000000 7.000000 9.000000 
forke = 0  yani child 0
begin loop 11
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 504
3.000000 3.000000 0.000000 3.000000 
7.000000 5.000000 8.000000 5.000000 
6.000000 1.000000 3.000000 6.000000 
8.000000 3.000000 3.000000 0.000000 
forke = 0  yani child 0
begin loop 12
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 507
6.000000 5.000000 1.000000 8.000000 
7.000000 3.000000 9.000000 7.000000 
9.000000 4.000000 0.000000 5.000000 
1.000000 6.000000 9.000000 3.000000 
forke = 0  yani child 0
begin loop 13
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 513
6.000000 4.000000 6.000000 3.000000 
5.000000 6.000000 6.000000 0.000000 
2.000000 1.000000 5.000000 2.000000 
7.000000 3.000000 9.000000 8.000000 
forke = 0  yani child 0
begin loop 14
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 515
0.000000 3.000000 7.000000 8.000000 
9.000000 1.000000 2.000000 4.000000 
5.000000 7.000000 4.000000 8.000000 
3.000000 1.000000 1.000000 6.000000 
forke = 0  yani child 0
begin loop 15
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 517
0.000000 8.000000 9.000000 7.000000 
7.000000 3.000000 3.000000 0.000000 
4.000000 0.000000 8.000000 1.000000 
5.000000 8.000000 4.000000 4.000000 
forke = 0  yani child 0
begin loop 16
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 520
8.000000 3.000000 8.000000 8.000000 
1.000000 7.000000 0.000000 3.000000 
4.000000 2.000000 0.000000 3.000000 
8.000000 4.000000 4.000000 8.000000 
forke = 0  yani child 0
begin loop 17
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 522
9.000000 3.000000 9.000000 3.000000 
3.000000 3.000000 2.000000 9.000000 
9.000000 3.000000 6.000000 0.000000 
8.000000 0.000000 8.000000 1.000000 
forke = 0  yani child 0
begin loop 18
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 524
9.000000 1.000000 4.000000 3.000000 
4.000000 8.000000 9.000000 2.000000 
2.000000 5.000000 0.000000 6.000000 
9.000000 0.000000 5.000000 7.000000 
forke = 0  yani child 0
begin loop 19
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 526
2.000000 0.000000 5.000000 3.000000 
1.000000 2.000000 1.000000 3.000000 
3.000000 6.000000 5.000000 8.000000 
7.000000 3.000000 2.000000 5.000000 
forke = 0  yani child 0

请注意,客户端在 20 个循环后整齐地退出;它可能应该更小。

一些变化

  • 代码only calls srand() once
  • 代码在扰乱 FIFO 之前设置服务器信号处理程序。
  • 代码不再循环删除 FIFO。
  • 代码不再将 signalcheck 设置为零,除非它是一。一个问题似乎是每次检查时“signalcheck”变量都为零。
  • 代码使用static volatile sig_atomic_t signalcheck
  • fork() 之前生成随机矩阵,以便看到不同的结果。
  • 服务器清理死去的 child (僵尸)。
  • 确实不清楚为什么服务器或子进程会 fork ,但或多或​​少会保留原样。
  • signal handler doesn't use printf() .

仍需改进

代码远非完美。有很多事情需要解决,包括:

  • 正确处理错误(例如在服务器中的 fork() 之后)。
  • 除中断外终止服务器的机制。
  • 检测客户端何时停止。
  • 不使用信号告诉服务器有工作。
  • 删除客户端 fork 。
  • 决定服务器是否真的需要 fork 。
  • 使用可配置的 FIFO 名称。
  • 更好地整理矩阵初始化。

关于c - While 循环中的 FIFO 卡住并等待读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43441561/

相关文章:

c - strcmp 没有正确比较字符串

linux - 需要有关 tar 命令的帮助

c - 使用 2 个管道的 3 个进程同步

c - C 程序中从指针运行函数

c - 测量进程及其子进程的时间

c - 如何从内核模块打开/写入/读取 uart 设备?

c - while、switch、case语句

c - C语言中华氏度到摄氏度

c - 以编程方式确定文件系统 block 大小

Perl fork exec,父系统中的系统并杀死子系统