Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

golang version: prime sieve 理解笔记 #8

Open
wisecsj opened this issue Jan 9, 2019 · 3 comments
Open

golang version: prime sieve 理解笔记 #8

wisecsj opened this issue Jan 9, 2019 · 3 comments

Comments

@wisecsj
Copy link
Owner

wisecsj commented Jan 9, 2019

代码如下:

// A concurrent prime sieve
package main

import "fmt"

// Send the sequence 2, 3, 4, ... to channel 'ch'.
func Generate(ch chan<- int) {
    for i := 2; ; i++ {
        ch <- i // Send 'i' to channel 'ch'.
    }
}

// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
func Filter(in <-chan int, out chan<- int, prime int) {
    for {
        i := <-in // Receive value from 'in'.
        if i%prime != 0 {
            out <- i // Send 'i' to 'out'.
        }
    }
}

// The prime sieve: Daisy-chain Filter processes.
func main() {
    ch := make(chan int) // Create a new channel.
    go Generate(ch)      // Launch Generate goroutine.
    for i := 0; i < 10; i++ {
        prime := <-ch
        fmt.Println(prime)
        ch1 := make(chan int)
        go Filter(ch, ch1, prime)
        ch = ch1
    }
}

理解golang的并发模式,在我看来,有两种方式:宏观的和微观的

所谓宏观,就是不去在意程序的执行逻辑和顺序,将关注放在程序的实现算法,并把无缓冲channel当作一个在不同goroutines之间传递消息的同步pipe。

所谓微观,就是利用分析工具,来将程序的执行逻辑可视化。譬如这篇非常好的文章:go_concurrency_visualize,就是利用分析工具+WebGL制作3D可视化动画,将程序的运行过程给形象的展示了出来。

image

@wisecsj
Copy link
Owner Author

wisecsj commented Jan 9, 2019

下面说理解。

本质上这个程序就是个Daisy-chain,从上面的图可以看出,也和之前rob pike在go concurrency patterns里介绍的一样。

这个chain的源头是Generate(),然后将数据流传给Filter-1,进行过滤后,将数据流传递给Filter-2 ,以此类推

并且在每次数据流传递的时候,取第一个(素数)传给main并输出

@wisecsj wisecsj pinned this issue Mar 9, 2019
@wisecsj wisecsj unpinned this issue Mar 10, 2019
@wisecsj
Copy link
Owner Author

wisecsj commented Jul 7, 2021

这是mit 6.828里lab1的一个作业,求一定数范围内的素数。用的也是上面的素数筛选法,并且要求并发实现

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int main(int argc, char *argv[])
{

    int i;
    int p_in[2];
    pipe(p_in);

    for (i = 2; i <= 35; i++)
    {
        write(p_in[1], &i, 4);
    }
    close(p_in[1]);

again:;
    int num, prime;
    int read_num;
    read_num = read(p_in[0], &num, 4);
    if (read_num != 0)
    {
        fprintf(1, "prime %d\n", num);
    }
    else
    {
        // fprintf(1, "error", "1");
        exit(0);
    }
    prime = num;

    int p_out[2];
    pipe(p_out);
    int pid;
    pid = fork();
    if (pid == 0)
    {
        close(p_out[1]);
        p_in[0] = p_out[0];
        goto again;
    }
    else
    {
        while (read(p_in[0], &num, 4) != 0)
        {
            if ((num % prime) != 0)
            {
                write(p_out[1], &num, 4);
            }
        }
        close(p_in[0]);
        close(p_out[1]);
        wait(0);
    }

    exit(0);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant