标签: goroutine

深入探讨 Goroutine

我试图理解 golang 架构以及“轻量级线程”的含义。我已经读过一些内容,但想提出问题来澄清它。

如果我说幕后的“go”关键字只是将以下函数放入内部线程池的队列中,但对于用户来说,它看起来像是创建线程,我是对的吗?

go goroutine

0
推荐指数
1
解决办法
1389
查看次数

尝试更新地图时的竞争条件

介绍

我正在尝试在 /go 中构建客户端服务器应用程序。

服务器只有一个实例,其中包含任务列表,这些任务只是字符串数据。服务器维护任务映射及其分配状态。

另一方面,客户端可以有多个实例,并向服务器请求任务。当分配任务时,服务器将分配状态更新为 true。

客户端和服务器之间的通信是通过go rpc进行的。

请参考这个图表为了更好的理解。

为了模拟多个客户端,我在单个应用程序中启动多个 go 例程,向服务器发出请求。

代码

服务器

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/rpc"
    "sync"
)

type Container struct {
    mu   sync.Mutex
    list map[string]bool
}

var ListOfTasks Container

func (c *Container) UpdateList() string {
    var t string
    ListOfTasks.mu.Lock()
    defer ListOfTasks.mu.Unlock()
    for k, v := range c.list {
        if !v {
            c.list[k] = true
            fmt.Println("Task Name", k)
            return k
        }
    }
    return t
}

// RPC Code
type RPCServer struct{}

type …
Run Code Online (Sandbox Code Playgroud)

rpc go race-condition goroutine

0
推荐指数
1
解决办法
172
查看次数

为什么在这种情况下主协程会被阻塞从而导致死锁?

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)
}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    for i := 0; i < 10; i++ {
        numbers <- i
    }
    close(numbers)

    for s := range squares {
        fmt.Println(s)
    }
}


Run Code Online (Sandbox Code Playgroud)

我的意思是,我知道要使这段代码正常工作,应该将数字发送到numbers单独的 goroutine 中的通道,例如:

go func() {
for i := 0; i < 10; i++ { …
Run Code Online (Sandbox Code Playgroud)

go goroutine

0
推荐指数
1
解决办法
63
查看次数

为什么分配有 time.Afterfunc 的 Timer 变量即使外部 func 退出也会执行其函数

我有一个永远循环,它有一个 Timer 变量,在一段时间后执行一个函数。

package main

import (
    fmt "fmt"
    "time"
)

func exe() {
    fmt.Println("10-seconds-of-time-is-done")
}

func t() {
    var timerCheck *time.Timer
    fmt.Println("here's the timerCheck", timerCheck)
    for {
        timerCheck = time.AfterFunc(10*time.Second, func() { exe() })
        fmt.Println("exiting-from-function-t")
        return
    }
}

func main() {
    t()
    fmt.Println("waiting-inside-main")
    time.Sleep(20 * time.Second)
}

Run Code Online (Sandbox Code Playgroud)

这是输出。我不明白该函数t()立即返回,而是在 10 秒后timerCheck执行其exe()函数。

here's the timerCheck <nil>
exiting-from-function-t
waiting-inside-main
10-seconds-of-time-is-done
Run Code Online (Sandbox Code Playgroud)

这怎么可能?在标准库中,关于AfterFunc

// AfterFunc waits for the duration to elapse and then calls f
// in …
Run Code Online (Sandbox Code Playgroud)

concurrency timer go goroutine

0
推荐指数
1
解决办法
37
查看次数

在golang中的缓冲通道上并发读取时发生冲突?

我有一个缓冲的通道,可以通过多个(在此示例中为4)go例程读取。

queue := make(chan string, 10000) // a large buffered channel
Run Code Online (Sandbox Code Playgroud)

每个go例程都会检查通道中可用的元素数量,并对所有元素进行处理。

for i :=0; i< 4; i++{ // spun 4 go routines
    go func() {
        for {
            for elem := range queue {
                // do something with the elem from the channel
            }
         }
     }
  }
Run Code Online (Sandbox Code Playgroud)

多个go例程会在读取时发生冲突吗?换句话说,不同的go例程可以在通道中捕获相同的元素,还是一个go例程正在读取缓冲区,而另一个go例程已经读取并处理了某些元素?如何在阅读一个go例程的同时阻止其他go例程读取?

channel go goroutine

-1
推荐指数
1
解决办法
1104
查看次数

goroutine中更新全局变量的不同行为

我有一个如下所示的程序。它启动NumberOfCPUs-1goroutines 并且在每个 goroutine 中只更新全局变量x。输出是x = 0

func main() {
    var x int
    threads := runtime.GOMAXPROCS(0)-1
    for i := 0; i < threads; i++ {
        go func() {
            for {
                x++
            }
        }()
    }
    time.Sleep(time.Second)
    fmt.Println("x =", x)
}
Run Code Online (Sandbox Code Playgroud)

如果我稍微改变一下程序,就像这样:

func main() {
    var x int
    threads := runtime.GOMAXPROCS(0)
    for i := 0; i < threads; i++ {
        go func() {
            for {
                x++
                time.Sleep(0)
            }
        }()
    }
    time.Sleep(time.Second)
    fmt.Println("x =", x)
}
Run Code Online (Sandbox Code Playgroud)

x 将是一些随机的大值。 …

go goroutine

-1
推荐指数
1
解决办法
3884
查看次数

使用gorountine的多线程

我正在尝试使用Go自动化我的侦察工具.到目前为止,我可以在kali(Nikto/whois)中运行两个基本工具.现在我希望它们并行执行,而不是等待一个函数完成.读了一下之后,我才知道这可以通过使用goroutines来实现.但我的代码似乎不起作用:

package main

import (
    "log"
    "os/exec"
    "os"
    "fmt"
)

var url string

func nikto(){
    cmd := exec.Command("nikto","-h",url)
    cmd.Stdout = os.Stdout
    err := cmd.Run()
    if err != nil {
        log.Fatal(err)
    }
}

func whois() {
    cmd := exec.Command("whois","google.co")
    cmd.Stdout = os.Stdout
    err := cmd.Run()
    if err !=nil {
        log.Fatal(err)
    }
}

func main(){
    fmt.Printf("Please input URL")
    fmt.Scanln(&url)
    nikto()
    go whois()
}
Run Code Online (Sandbox Code Playgroud)

我明白在这里,go whois()会一直执行main(),但我仍然看不到它们都执行并行.

go goroutine

-1
推荐指数
1
解决办法
57
查看次数

为什么调用goroutine的顺序和方式很重要?

我正在尝试了解goroutine。在下面的示例中,为什么1)-4)表现不同?参见https://play.golang.org/p/_XXZe47W53v

package main
import (
  "fmt"
  "time"
)

func send(x int, ch chan int) {ch<-x}
func read(ch chan int) {fmt.Println(<-ch)}

func main() {
    ch := make(chan int)

    go read(ch)              // 1) works
    go send(1,ch)            // -> 1

    // go fmt.Println(<-ch)  // 2) fatal error: all goroutines are asleep - deadlock!
    // go send(1,ch)         // isn't this the same as the above ?

    // go send(1,ch)         // 3) works
    // go fmt.Println(<-ch)  // -> 1

    // go fmt.Println(<-ch)  // 4) …
Run Code Online (Sandbox Code Playgroud)

go goroutine

-1
推荐指数
1
解决办法
47
查看次数

通道何时阻止goroutine

如果我定义了一个没有缓冲区的通道并向其中写入一个数据,它会立即阻塞吗(以便内核将寻找从该通道读取的另一个不受阻塞的goroutine),或者它会继续执行并在下次尝试某些代码时阻塞在尚未读取该通道时再次写入该通道?

以下是我编写的用于研究此问题的两段代码。

代码1:

package main

import "fmt"

func main() {
    c := make(chan int)
    go func() {
        for i := 0;i < 3; i++ {
            c <- i
            fmt.Printf("number %v inserted into channel\n", i)
        }
    }()
    for i := 0; i < 3; i++ {
        fmt.Printf("number poped from channel %v\n", <-c)
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是这样的:

number 0 inserted into channel
number poped from channel 0
number poped from channel 1
number 1 inserted into channel
number 2 inserted into channel
number …
Run Code Online (Sandbox Code Playgroud)

go goroutine

-1
推荐指数
1
解决办法
63
查看次数

了解互斥体行为

我在想mutex在 Go 中会锁定数据并且不允许任何其他人读/写,goroutine除非拳头goroutine释放锁。看来我的理解是错误的。阻止其他人读/写的唯一方法goroutine是调用lock其他goroutines人。这将确保critical section只有一个访问goroutine

所以,我希望这段代码有一个死锁:

package main

import(
    "fmt"
    "sync"
)

type myMap struct {
    m map[string]string
    mutex sync.Mutex
}

func main() {
    done := make(chan bool)
    ch := make(chan bool)
    myM := &myMap{
        m:     make(map[string]string),
    }
    go func() {
        myM.mutex.Lock()
        myM.m["x"] = "i"
        fmt.Println("Locked. Won't release the Lock")
        ch <- true
    }()

    go func() {
        <- ch
        fmt.Println("Trying to write to …
Run Code Online (Sandbox Code Playgroud)

multithreading mutex go goroutine

-1
推荐指数
1
解决办法
142
查看次数

标签 统计

go ×10

goroutine ×10

channel ×1

concurrency ×1

multithreading ×1

mutex ×1

race-condition ×1

rpc ×1

timer ×1