When executing the following code I get what I expect when the first loop is done (sequence from 0 to 9). But when the second loop finishes, the result is not what I expected (I expected the same result as in the first loop, but it prints only '10's):
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(j int) {
defer wg.Done()
fmt.Println(j)
}(i)
}
wg.Wait()
fmt.Println("done first")
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println(i)
}()
}
wg.Wait()
fmt.Println("done second")
}
Output:
0
1
2
3
4
5
6
7
8
9
done first
10
10
10
10
10
10
10
10
10
10
done second
Why doesn't the second loop print a sequence?
Because the first one gets a copy of the loop counter each time. Whereas the second gets the variable captured as part of a closure.
In the first, you're passing it in here in every iteration of the loop:
go func(j int) {
defer wg.Done()
fmt.Println(j)
}(i) // <------------ its passed in here as part of each loop iteration
The second one receives nothing.. so, the loop counter i is captured as part of a closure. By the time the first go routine executes, the for loop has finished. The loop finishing has set the i variable (that is now part of a closure) to 10. Go routine #1 executes and prints the value of i.. which is now already 10 and the rest follow suit.
TLDR: The problem here is that the loop is finishing before any go routines are scheduled to be run - its just that quick. Therefore, i == 10 when the go routines run.
Related
Both NUM and ARRAY double precision variables, not sure how the if block will execute. When will it stop? What is it actually doing?, If we go to 8, then are we exiting the do loop?
Thanks
DO 7 I = 1,28
IF (NUM - ARRAY(I)) 8,7,7
7 CONTINUE
I=29
8 NUM = ARRAY(I)
....
....
....
....
As previously stated the conditional in the loop is an arithmetic if statement.
We know (and that's explicitly stated in the previous answer here) that if num is less than array(i) the label 8 is chosen, otherwise label 7 is chosen. It's also stated in that other answer that these have the effect of exiting the loop or cycling it. To be precise, I'll continue.
A DO construct has a range. A nonblock DO construct like the one in the question has range consisting of the statements between and including the do statement and the DO termination statement (in this case 7 continue). The DO termination statement is a valid target for a jump from within the range of the construct.
When the DO termination statement is jumped to, execution remains within the scope of the construct. That termination statement is executed (in this case, continue, doing nothing) and the loop iteration condition is again tested. That is, the loop cycles.
From within a DO construct, a jump to a statement outside the range of the construct terminates execution of the construct: like an exit.
This example, then, has the equivalent form using an IF construct (with go tos - bear with me)
DO 7 I = 1,28
IF (NUM < ARRAY(I)) THEN
GO TO 8
ELSE
GO TO 7
END IF
7 CONTINUE
I=29
8 NUM = ARRAY(I)
Now, because the statement labelled 7 is a continue statement, we can write this as
DO 7 I = 1,28
IF (NUM < ARRAY(I)) THEN
GO TO 8
ELSE
CYCLE
END IF
7 CONTINUE
I=29
8 NUM = ARRAY(I)
That's still pretty ugly (and not just because of all the upper case). Fortunately, we can make this prettier. The i=29 statement will be executed only when the loop terminates without the statement labelled 8 being jumped to. Now, the loop index i has control I = 1,28 so when the loop terminates naturally the index already has the value 29. That assignment does nothing (in modern Fortran) so we can remove it. Which leaves us with
DO 7 I = 1,28
IF (NUM < ARRAY(I)) THEN
GO TO 8
ELSE
CYCLE
END IF
7 CONTINUE
8 NUM = ARRAY(I)
When we also note that the IF construct is immediately followed by the end of the loop (and so we don't need to explicitly cycle) we have
DO 7 I = 1,28
IF (NUM < ARRAY(I)) EXIT
7 CONTINUE
NUM = ARRAY(I)
or (more nicely)
DO I = 1,28
IF (NUM < ARRAY(I)) EXIT
END DO
NUM = ARRAY(I)
All this example is doing is finding the value of the earliest element in array(1:28) which is larger than num, or array(29) if none is.
That is called arithmetic if: if(a) 1,2,3 . and it means: if a<0 it goes to 1, if(a==0) it goes to 2 and if (a>0) it goes to 3.
in your code if( num-array(i)<0 ) it goes to 8 (exit the loop and skip another line), else it goes to 7 (cycle).
i have an problem with GCD in swift 3
i create the concurrent queue and i pass function in this queue this function call another function
i need to print the elapsed time for each call
but i think the implementation is cut within the concurrent queue the following my code :
// peform task with the concurrent queue
class DoCalculations{
func doCalc() {
let x = 100
let y = x * x
_ = y / x
}
func performCalculation(itretion:Int,tag:String) {
let start = CFAbsoluteTimeGetCurrent()
for _ in 0..<itretion {
self.doCalc()
}
let end = CFAbsoluteTimeGetCurrent()
print("tag :\(tag) : \(end - start)")
}
}
let calc = DoCalculations()
let cQueue = DispatchQueue(label: "com.myCompany", attributes: .concurrent)
cQueue.async {
calc.performCalculation(itretion: 1000000, tag: "sync1")
}
cQueue.async {
calc.performCalculation(itretion: 1000, tag: "sync2")
}
cQueue.async {
calc.performCalculation(itretion: 100000, tag: "sync3")
}
// the print function is not Excuted
please can solve this issues
If you're doing this on a playground, you want to indicate that execution should continue "after the end of the playground’s top-level code is reached." You do this with needsIndefiniteExecution:
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
As the documentation for needsIndefiniteExecution says:
A Boolean value that indicates whether indefinite execution is enabled.
By default, all top-level code is executed, and then execution is terminated. When working with asynchronous code, enable indefinite execution to allow execution to continue after the end of the playground’s top-level code is reached. This, in turn, gives threads and callbacks time to execute.
Editing the playground automatically stops execution, even when indefinite execution is enabled.
Set needsIndefiniteExecution to true to continue execution after the end of top-level code. Set it to false to stop execution at that point.
The default value is false. It is set to true when liveView is set to a non-nil value.
Example of concurrent queue using gcd
func callGCDWithConcurrentQueue(){
let dispatchQueue = DispatchQueue(label: "Dmoe",qos:.utility,attributes: .concurrent)
dispatchQueue.async{ // Task 1
for i in 0...10{
print(i)
}
}
dispatchQueue.async{ //Task 2
for i in 10...20{
print(i)
}
}
}
callGCDWithConcurrentQueue() > // Calling Method
// OutPut
/
0
10
1
2
3
4
11
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
/
I have written my own sleep function and want to test it. Following is my code:
func TestSleep(t *testing.T) {
start := time.Now()
mySleepFunction(65)
end := time.Now()
if (end - start) != 65 {
t.Error("Incorrect sleep function")
}
}
This is not working. I am trying to get start time and end time and then compare it with expected time. The expected time will be in seconds. I tried end.Sub(start) but this returns me something like 1m30.0909, instead I need 90 as a result. It would be great if someone could help me.
Thanks :)
Elapsed time:
The easiest to get the elapsed time since a specific time (start) is to use the time.Since() function which returns a time.Duration which has a Duration.Seconds() method which returns the duration in seconds as float64.
So in your case the elapsed seconds:
sec := time.Since(start).Seconds()
Now on to testing...
When testing sleep-like functions you should take into consideration that after the sleep it is not guaranteed that the code will continue to execute immediately. For example quoting from the doc of time.Sleep():
Sleep pauses the current goroutine for at least the duration d.
So when writing test code for sleep-like functions, I would test like this:
elapsed time should be at least the specified,
and allow some error margin.
So for example test it like this:
func TestSleep(t *testing.T) {
const secSleep = 65.0
start := time.Now()
mySleepFunction(int(secSleep))
sec := time.Since(start).Seconds()
if sec < secSleep || sec > secSleep*1.05 {
t.Error("Incorrect sleep function")
}
}
If you use time.Unix() which gives you the amount of seconds since the epoch (January 1, 1970 UTC.) then your test should work.
func TestSleep(t *testing.T) {
start := time.Now().Unix()
mySleepFunction(65)
end := time.Now().Unix()
if (end - start) != 65{
t.Error("Incorrect sleep function")
}
}
Currently, your code is subtracting a time.Now() which doesn't return the result you intend. Your test wants simple int values that represent seconds.
I want to create a producer/consumer with manager program in Go. For example: I have a 5 producers, 5 consumers and manager. Producers have their own local arrays, they iterate over them and send the elements to the manager. Consumers have their own local arrays with info that elements consume; they send them to the manager too. The Manager has it own array, where it stores what and how many elements there are (for example - if the producer sends 1 1 2 3 1 2 0 elements, the manager array looks like 1 3 2 1 (one 0, three 1, two 2 and one 3 ) and it handles producers' and consumers' requests - placing an element into the array (produce) or removing it (consume).
Is it possible to make a program like this in Go? I already did this in JAVA + CSP with channels to send info and guards in the manager to determine which procedure should be done first when producer and consumer try to process the same element (for example, a producer wants to add 1 to the manager array and at the same time a consumer wants to consume 1).
Any examples or advice are welcome, because I don't find any info about what I want to do. If needed I can give my JAVA+CSP code.
UPDATE. How about synchronization (not to take from empty array)? For example - if consumer wants to consume element from manager array that does not exist yet (for example consumer wants to consume '3', but manager don't have any of thems) but producer has this element and it will be produced after few iterations - how can I make consumers to check manager array again and again until producers work is finished? Should I need to create structs (or classes) for consumers elements and mark that they are used or not, or Go has specific methods to do this?
Here's a full example, including channel cleanup. After all the consumers and producers are finished, the Manager prints out the result (for which I've used a map rather than a slice, since I think it makes the code a tad easier).
package main
import "fmt"
// Consume processes the numbers in ns, sending them on ch after they're
// processed. When the routine is finished, it signals that on done.
func Consume(done chan bool, ch chan int, ns []int) {
for i := range ns {
ch <- i
}
done <- true
}
// Produce "creates" the numbers in ns, sending them on ch after they're
// produced. When the routine is finished, it signals that on done.
func Produce(done chan bool, ch chan int, ns []int) {
for i := range ns {
ch <- i
}
done <- true
}
// Manage creates consumers and producers for the given int slices.
// It returns once all consumers and producers are finished.
func Manage(cons, pros [][]int) {
cch := make(chan int)
pch := make(chan int)
dch := make(chan bool)
n := len(cons) + len(pros)
data := make(map[int]int)
for _, c := range cons {
go Consume(dch, cch, c)
}
for _, p := range pros {
go Produce(dch, pch, p)
}
for n > 0 {
select {
case c := <-cch:
data[c] -= 1
case c := <-pch:
data[c] += 1
case <-dch:
n -= 1
}
}
close(cch)
close(pch)
close(dch)
fmt.Println(data)
}
func main() {
cons := [][]int{{1, 3, 5}, {0, 1, 5}}
pros := [][]int{{0, 1, 1}, {3, 5, 5, 7}}
Manage(cons, pros)
}
I did a very similar example to what you're trying to do, check this gist github gist
The way I implemented that is using a single channel for my process consumer and another for my 2x processes that produce items, the for block controls the push from producers to the consumer and whenever the producers arent pushing anything the loop will default. The objects moved through the channels are slices, processes would produce and consume the headlines in each slice sent through the channel. I believe you can adjust this code to fit your example.
I am new to Golang. Right now I am trying to figure out how to make an any-to-one channel in Golang, where the setup is as follows:
say I have two goroutines numgen1 and numgen2 executing concurrently and writing numbers to channels num1 resp. num2. I would like to add the numbers sent from numgen1 and numgen2 in a new process, addnum. I have tried something like this:
func addnum(num1, num2, sum chan int) {
done := make(chan bool)
go func() {
n1 := <- num1
done <- true
}()
n2 := <- num2
<- done
sum <- n1 + n2
}
but this seems sadly incorrect. Could someone please give me some ideas?
Thank you very much for your help.
Depending on your requirements, you may need to read both of the channels for every iteration (i.e. a sort-of 'zip' function). You can do this with a select, similarly to user860302's answer:
func main() {
c1 := make(chan int)
c2 := make(chan int)
out := make(chan int)
go func(in1, in2 <-chan int, out chan<- int) {
for {
sum := 0
select {
case sum = <-in1:
sum += <-in2
case sum = <-in2:
sum += <-in1
}
out <- sum
}
}(c1, c2, out)
}
This runs forever. My preferred way to terminate goroutines like this one is to close the input channels. In this case you would need to wait for both to close, then close(out) before terminating.
Tip: note the use of directional channels as goroutine formal parameters. The compiler catches more mistakes when you write it this way. Happiness!
The simplest answer would be
func addnum(num1, num2, sum chan int) {
n1 := <- num1
n2 := <- num2
sum <- n1 + n2
}
Since you need both num1 and num2 to do the calculation, it makes no sense to do it otherwise. After all, there are two possible execution orders:
num1 generates a number, followed by num2
num2 generates a number, followed by num1
In the first case, our channel reads correspond exactly to the execution order. In the second case, our first read will block until num1 has finally produced a number; the second read will complete near-instantaneous because the num2 channel already has a number.
If you want to know more about channels in Go, I'd suggest to have a look at http://godoc.org/github.com/thomas11/csp -- this is a collection of Hoare's CSP examples written in Go.
To answer the question "Reading from multiple channels simultaneously"
There is a way to listen to multiple channels simultaneously :
func main() {
c1 := make(chan string)
c2 := make(chan string)
...
go func() {
for {
select {
case msg1 := <- c1:
fmt.Println(msg1)
case msg2 := <- c2:
fmt.Println(msg2)
}
}
}()
In this example, I create a channel msg1 and msg2.
Then I create a go routine with an infinite loop. In this loop, I listen to msg1 AND msg2.
This system allow you to read to multiple channels simultaneously and to process the messages when the arrive.
In order to avoid leaks, I should probably add another channel to stop the goroutine.