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




Bài đăng trên chuyên mục Lập trình vào ngày 5 tháng 2 năm 2016 bởi manhhomienbienthuy. Chỉnh sửa lần cuối lúc 13:47:48 ngày 28 tháng 7 năm 2021 (JST).

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

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(intparentfd)
{
pid_tpid;
intbuf,divider=0,len,pipefd[2],childfd=-1;

while(1)
{
len=read(parentfd,&buf,sizeof(buf));
if(divider==0)
{
divider=buf;
printf("%d\n",divider);
}
elseif(buf<0)
{
if(childfd!=-1)
write(childfd,&buf,sizeof(buf));
break;
}
elseif(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_tpid;
intpipefd[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);

return0;
}
#C #system programming #prime

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

Bài viết liên quan




Bài viết mới




Chuyên mục




Lưu trữ theo năm




Câu nói yêu thích




There's a big difference between knowing the name of something and knowing something.

– Richard P. Feynman –

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.