System programming references

Posted in Programming on February 05, 2016 by manhhomienbienthuy Comments
System programming references

Một chương trình và in ra các số nguyên tố. Sử dụng fork (và pipeline), nó sẽ sinh ra các tiến trình con. Trong quá trình kiểm tra các số, các tiến trình con tương ứng với các số nguyên tố sẽ lần lượt được tạo ra. Quá trình có thể mô tả đơn giản như dưới đây.

Với mỗi số từ 2 trở nên

  • Tiến trình đầu tiên nhận số 2 là số nguyên tố
  • Với số 3, nó không chia hết cho 2 (ở tiến trình đầu) nên nó sẽ là số nguyên tố => fork thêm một tiến trình và kiểm tra xem các số có chia hết cho 3 không
  • 4 chia hết cho 2 nên không nguyên tố
  • 5 không cho hết cho cả 2 và 3 nên là nguyên tố => fork thêm một tiến trình kiểm tra các số chia hết cho 5.
  • Cứ như vậy, với mỗi số cần kiểm tra, nó sẽ được chuyển qua lần lượt các tiến trình, nếu vượt qua hết, nó chính là số nguyên tố.
  • Cuối cùng, in số đang lưu trữ trong các tiến trình là chúng ta có danh sách các số nguyên tố.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define FIRST_PRIME_NUMBER 2
#define MAX_PRIME_NUMBER 1000

void
child_process (int parentfd)
{
  pid_t pid;
  int buf, divider = 0, len, pipefd[2], childfd = -1;

  while (1)
    {
      len = read (parentfd, &buf, sizeof (buf));
      if (divider == 0)
        {
          divider = buf;
          printf ("%d\n", divider);
        }
      else if (buf < 0)
        {
          if (childfd != -1)
            write (childfd, &buf, sizeof (buf));
          break;
        }
      else if (buf % divider != 0)
        {
          if (childfd == -1)
            {
              if (pipe (pipefd) < 0)
                break;
              pid = fork ();
              if (pid == 0)
                {
                  parentfd = pipefd[0];
                  close (pipefd[1]);
                  divider = 0;
                }
              else
                {
                  childfd = pipefd[1];
                  close (pipefd[0]);
                }
            }
          if (childfd != -1)
            write (childfd, &buf, sizeof (buf));
        }
    }

  return;
}

int
main ()
{
  pid_t pid;
  int pipefd[2], i;

  if (pipe (pipefd) < 0)
    {
      fprintf (stderr, "failed to initialize pipe");
      return -1;
    }

  pid = fork ();
  if (pid == 0)
    {
      close (pipefd[1]);
      child_process (pipefd[0]);
    }
  else
    {
      close (pipefd[0]);
      for (i = FIRST_PRIME_NUMBER; i <= MAX_PRIME_NUMBER; i++)
        {
          write (pipefd[1], &i, sizeof (i));
        }

      i = -1;
      write (pipefd[1], &i, sizeof (i));
    }

  wait (NULL);

  return 0;
}

I apologise for any typos. If you notice a problem, please let me know.

Thank you all for your attention.