Code hay quá (không phải của tôi) nên lưu lại để nhớ

Code hay quá (không phải của tôi) nên lưu lại để nhớ
Photo by Андрей Сизов from Unsplash

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ố.

Dưới đây là code, mình thấy hay quá nên lưu lại để nhớ. Code này của một phó giáo sư (tôi quên mất tên rồi 😥), trợ giảng cho giáo sư Nakamura Osamu (osamu) môn lập trình mạng (không liên quan lắm 🤣).

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

Tôi xin lỗi nếu bài viết có bất kỳ typo nào. Nếu bạn nhận thấy điều gì bất thường, xin hãy cho tôi biết.

Nếu có bất điều gì muốn nói, bạn có thể liên hệ với tôi qua các mạng xã hội, tạo discussion hoặc report issue trên Github.

Welcome

manhhomienbienthuy

Đây là thế giới của manhhomienbienthuy (naa). Chào mừng đến với thế giới của tôi!

Bài viết liên quan

Bài viết mới

Chuyên mục

Lưu trữ theo năm

Thông tin liên hệ

Cảm ơn bạn đã quan tâm blog của tôi. Nếu có bất điều gì muốn nói, bạn có thể liên hệ với tôi qua các mạng xã hội, tạo discussion hoặc report issue trên Github.