search
HomeBackend DevelopmentPython TutorialDetailed examples of for-loop and goroutine in Golang

This article mainly introduces to you the relevant information about for-loop and goroutine issues in Golang. The article introduces it in detail through sample code. It has certain reference learning value for everyone to learn or use golang. Friends who need it Let’s learn with the editor below.

Background

#Recently, while studying MIT’s distributed course 6.824, I encountered some problems when using Go to implement the Raft protocol. question. I share it for everyone’s reference and study. I won’t say much below, let’s take a look at the detailed introduction.

See the following code:


for i := 0; i < len(rf.peers); i++ {
  DPrintf("i = %d", i)

  if i == rf.me {
   DPrintf("skipping myself #%d", rf.me)
   continue
  }

  go func() {
   DPrintf("len of rf.peers = %d", len(rf.peers))
   DPrintf("server #%d sending request vote to server %d", rf.me, i)
   reply := &RequestVoteReply{}
   ok := rf.sendRequestVote(i, args, reply)
   if ok && reply.VoteGranted && reply.Term == rf.currentTerm {
    rf.voteCount++
    if rf.voteCount > len(rf.peers)/2 {
     rf.winElectionCh <- true
    }
   }
  }()
}

Among them, the length of the peers slice is 3, so the highest subscript is 2. The for-loop in the code in parallel programming should be very intuitive, and I didn't realize there was any problem at the time. However, during the debugging process, index out of bounds errors kept being reported. The debugging information showed that the value of i was 3. At that time, I still couldn’t figure out how the loop condition could become 3 when it was clearly i

Analysis

Although I don’t understand what happened, I know that it should be caused by the goroutine introduced in the loop. After Google, I found that there is a page in Go's wiki called Common Mistake - Using goroutines on loop iterator variables that specifically mentions this problem. It seems to be really common. I laugh and cry~

Beginners often use it Use the following code to process data in parallel:


for val := range values {
 go val.MyMethod()
}

Or use closure:


for val := range values {
 go func() {
  fmt.Println(val)
 }()
}

The problem here The reason is that val is actually a single variable that iterates through all the data in the slice. Since the closure is only bound to this val variable, it is very likely that the result of the above code is that all goroutines output the last element of the slice. This is because it is very likely that the goroutine will not start executing until after the for-loop is executed, and at this time the value of val points to the last element in the slice.


The val variable in the above loops is actually a single variable that takes on the value of each slice element. Because the closures are all only bound to that one variable, there is a very good chance that when you run this code you will see the last element printed for every iteration instead of each value in sequence, because the goroutines will probably not begin executing until after the loop.

Solution

The correct way to write the above code is:


for val := range values {
 go func(val interface{}) {
  fmt.Println(val)
 }(val)
}

Here, val is passed into the goroutine as a parameter. Each val will be independently calculated and saved to the goroutine's stack, thereby obtaining the expected results.

Another method is to define new variables within the loop. Since the variables defined within the loop are not shared during the loop traversal, the same effect can be achieved:


for i := range valslice {
 val := valslice[i]
 go func() {
  fmt.Println(val)
 }()
}

For the problem mentioned at the beginning of the article, the simplest solution is to add a temporary variable in the loop and replace all i in the subsequent goroutine with this temporary variable:


server := i

Summary

The above is the detailed content of Detailed examples of for-loop and goroutine in Golang. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Refactoring Python Code EffectivelyRefactoring Python Code EffectivelyJul 24, 2025 am 03:38 AM

Refactoring is not rewriting, but improving the code structure and readability without changing the function. Common reconstruction situations include too large functions or classes, many repetitive codes, fuzzy variable naming, and complex control processes. Refactoring should start with details, such as splitting large functions, extracting duplicate code, simplifying conditional judgment, and improving variable naming. Tools and testing are the key. Using pytest, black, isort, flake8, mypy and other tools to cooperate with unit testing can ensure that the changes are safe. Refactoring should be continuously optimized from a small way, rather than rewriting it all at once.

Python Memory Management ExplainedPython Memory Management ExplainedJul 24, 2025 am 03:38 AM

Python's memory management consists of automatic allocation and recycling mechanisms. When creating variables, memory will be allocated from the memory pool or system malloc according to the object size. Small objects preferentially use memory pools to improve efficiency. Memory recycling mainly relies on reference counting and garbage collector (gc module). Reference counting is zeroed and memory is released, while circular references are processed by garbage collector. To reduce memory usage, array, NumPy array, generator, and \_\_slots\_\_\_ can be used. The memory is not released immediately at the end of the del or function, which may be caused by garbage collection delay, external memory usage or object cache. You can use tracemalloc or memory\_profiler tools to analyze the memory situation.

python recursion examplepython recursion exampleJul 24, 2025 am 03:36 AM

Recursion is a method for function calls to solve problems in Python, and is suitable for scenarios such as factorial, Fibonacci sequence, nested list traversal and binary search. 1. Factorial is recursively calculated by n*factorial(n-1), and the basic situation is n==0 or 1, and the basic situation is n==0 or 1; 2. The Fibonacci sequence defines f(n)=f(n-1) f(n-2), and the basic situation is f(0)=0, f(1)=1, but the naive recursive efficiency is low, and it is recommended to use lru_cache to optimize; 3. When traversing the nested list, if the elements are lists, they will be processed recursively, otherwise they will be printed; 4. The binary search recursive version looks for the target value in an ordered array, and determines the recursive left and right intervals based on the comparison between the intermediate value and the target. The basic situation is low>hig

Customizing Logging Handlers in PythonCustomizing Logging Handlers in PythonJul 24, 2025 am 03:33 AM

The core of custom loggingHandler is to inherit logging.Handler and implement the emit() method, which is suitable for scenarios such as sending logs to emails, writing to databases, or pushing remote servers. 1. The situations that need to be customized include: pushing logs to Slack or DingTalk, recording to database or API, processing by level, and adding additional information; 2. The implementation method is to inherit logging.Handler and rewriting emit(), where you write custom logic such as sending HTTP requests; 3. When using it, you need to pay attention to exception handling, formatting output, setting appropriate levels and formatters, and avoid duplicate output and propagation problems.

What is the difference between python `break` and `continue`?What is the difference between python `break` and `continue`?Jul 24, 2025 am 03:33 AM

In Python, the difference between break and continue is that: 1.break is used to terminate the entire loop immediately, which is often used to exit the loop early or complete the search task; 2.continue only skips the current iteration and continues to execute the next loop, which is suitable for ignoring specific elements or filtering data. For example, use break after finding a match when searching a list, and skip invalid entries with continue when cleaning data. Although both control the cycle flow, their functions are completely different.

How to flatten a list of lists in PythonHow to flatten a list of lists in PythonJul 24, 2025 am 03:32 AM

There are three ways to tile nested lists in Python: First, use list comprehension, the syntax is [itemforsublistinlist_of_listsforiteminsublist], which is suitable for two-dimensional lists; Second, use itertools.chain, which includes itertools.chain.from_iterable(list_of_lists) or itertools.chain(*list_of_lists), which has better performance; Third, when dealing with irregular nesting, judgment statements need to be added, for example, using isinstance(sublist, list) to distinguish lists from non-

python threading lock examplepython threading lock exampleJul 24, 2025 am 03:29 AM

Threading.Lock is needed to prevent race conditions for shared resources in multi-threading environments. 1. Create lock object lock=threading.Lock(); 2. Use withlock: Ensure the operation atomicity of shared variables; 3. Multiple threads accumulate 100,000 times for counters, and the final result is correct 500,000; 4. It is recommended to use the with statement to automatically manage the acquisition and release of locks; 5. Avoid nested acquisition of locks, and use threading.RLock() if necessary; 6. The scope of the lock should be as small as possible to improve performance; 7. Pay attention to avoid deadlocks due to inconsistent locking order.

Scientific Computing with PythonScientific Computing with PythonJul 24, 2025 am 03:25 AM

Python is widely used in scientific computing because its mature libraries and tool chains can handle various tasks. Key points include: 1. Install core libraries such as NumPy (efficient arrays and mathematical functions), SciPy (advanced mathematical operations), Matplotlib (data visualization) and Pandas (table data processing), which can be installed through pip or conda; 2. Replace native lists with NumPy to improve performance, and support vectorized operations, broadcast mechanisms and linear algebra functions; 3. SciPy provides complex mathematical tools such as integral, optimization, and Fourier transform, such as using quad function to calculate definite integrals; 4. Matplotlib and its encapsulation library Seaborn are used for graph display, supporting style settings and professionalism

See all articles

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment