发布时间:2024-12-23 03:10:06
要创建一个goroutine,只需要在函数调用前加上关键字`go`即可:
```go func main() { go count() // do other things } func count() { for i := 0; i < 10; i++ { fmt.Println(i) time.Sleep(time.Second) } } ``` 在上述代码中,通过`go count()`创建了一个新的goroutine并开始执行`count`函数体。使用goroutine可以在不影响主线程的情况下,执行并发的任务。要创建一个channel,可以使用`make`函数:
```go ch := make(chan int) ``` 在默认情况下,channel是阻塞的,即当有goroutine发送(写入)或接收(读取)数据时,会阻塞当前的goroutine,直到对应的操作完成。这使得goroutine能够按照所需的顺序进行通信和同步。下面是一个使用channel进行消息传递的示例:
```go func main() { ch := make(chan string) go sendMessage(ch) go receiveMessage(ch) time.Sleep(time.Second) } func sendMessage(ch chan<- string) { ch <- "Hello, Golang!" } func receiveMessage(ch <-chan string) { msg := <-ch fmt.Println(msg) } ``` 在上述代码中,我们创建了一个只能写入的channel `ch`,并将其分别传递给`sendMessage`和`receiveMessage`两个函数。`sendMessage`将消息发送到channel中,而`receiveMessage`则从channel中接收并打印消息。下面是一个使用原子操作实现计数器的示例:
```go var counter int64 func main() { var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go increment(&wg) } wg.Wait() fmt.Println("Counter:", counter) } func increment(wg *sync.WaitGroup) { atomic.AddInt64(&counter, 1) wg.Done() } ``` 在上述代码中,我们使用了`atomic.AddInt64`函数对`counter`进行原子加1操作,从而避免了多个goroutine同时对`counter`进行写入造成的冲突。下面是一个使用互斥锁解决竞态条件问题的示例:
```go var counter int var mu sync.Mutex func main() { var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go increment(&wg) } wg.Wait() fmt.Println("Counter:", counter) } func increment(wg *sync.WaitGroup) { mu.Lock() counter++ mu.Unlock() wg.Done() } ``` 在上述代码中,我们使用互斥锁`mu`来保护对`counter`的访问。通过调用`mu.Lock()`和`mu.Unlock()`将临界区代码包裹起来,确保只有一个goroutine能够进入临界区。