Reputation: 1
I got these error
fatal error: all goroutines are asleep - deadlock!
`goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc0000081e0?)
C:/Program Files/Go/src/runtime/sema.go:71 +0x25
sync.(*WaitGroup).Wait(0x0?)
C:/Program Files/Go/src/sync/waitgroup.go:118 +0x48
main.main()`
But I use synchronization Wait() and other tools. What wrong? My code:
package main
import (
"fmt"
"sync"
)
func sender(id int, data []int, out chan<- [2]int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < len(data); i += 2 {
out <- [2]int{data[i], data[i+1]}
}
}
func service(in <-chan [2]int, c, d int, out chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for pair := range in {
sum := pair[0] + pair[1]
if sum >= c && sum <= d {
out <- sum
}
}
}
func receiver(in <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
line := 1
for sum := range in {
fmt.Printf("Line %d: Received sum %d\n", line, sum)
line++
}
}
func main() {
data1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
data2 := []int{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
data3 := []int{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
data4 := []int{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
c, d := 15, 50
senderToService := make(chan [2]int, 10)
serviceToReceiver := make(chan int, 10)
var wg sync.WaitGroup
// Start sender goroutines
wg.Add(4)
go sender(1, data1, senderToService, &wg)
go sender(2, data2, senderToService, &wg)
go sender(3, data3, senderToService, &wg)
go sender(4, data4, senderToService, &wg)
// Close senderToService channel once all senders are done
go func() {
wg.Wait()
close(senderToService)
}()
// Start service goroutine
wg.Add(1)
go service(senderToService, c, d, serviceToReceiver, &wg)
// Close serviceToReceiver channel once the service is done
go func() {
wg.Wait()
close(serviceToReceiver)
}()
// Start receiver goroutine
wg.Add(1)
go receiver(serviceToReceiver, &wg)
// Wait for all goroutines to finish
wg.Wait()
}
I am using a single WaitGroup (wg) to manage synchronization across three independent stages of the pipeline: The sender stage produces data. The service stage processes the data. The receiver stage consumes the processed data. When I call wg.Wait() in the main function, it waits for all decrements from all stages The channels senderToService and serviceToReceiver are closed in anonymous goroutines that wait on wg.Wait(). So where is root cause and how to fix it?
Upvotes: -4
Views: 124
Reputation: 1
#include <iostream>
#include <vector>
#include <omp.h>
#include <mutex>
int main() {
// Shared array to store computed values
std::vector<int> shared_array;
// Mutex to ensure thread-safe access to shared_array
std::mutex mtx;
// Total sum variable
int total_sum = 0;
// Number of threads
const int num_threads = 10;
// Parallel region
#pragma omp parallel num_threads(num_threads) reduction(+:total_sum)
{
// Get thread number (unique identifier for each thread)
int i = omp_get_thread_num();
// Compute the value of i^2 + i^3
int value = i * i + i * i * i;
// Append the result to the shared array
{
std::lock_guard<std::mutex> lock(mtx);
shared_array.push_back(value);
}
// Add the computed value to the total sum
total_sum += value;
}
// Print the contents of the shared array
std::cout << "Shared array contents: ";
for (int val : shared_array) {
std::cout << val << " ";
}
std::cout << std::endl;
// Print the total sum
std::cout << "Total sum: " << total_sum << std::endl;
return 0;
}
Upvotes: -3
Reputation: 41
The problem is that the application uses a single wait group to wait for three different events (senders done, service done, receiver done). The wait for sender
s does not complete because the group includes the count for service
. The service
goroutine does not complete because the program is still waiting on sender
s. Deadlock!
One fix is to change the program to use three wait groups. A simpler fix is to eliminate unnecessary use of wait groups.
func sender(id int, data []int, out chan<- [2]int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < len(data); i += 2 {
out <- [2]int{data[i], data[i+1]}
}
}
func service(in <-chan [2]int, c, d int, out chan<- int) {
defer close(out)
for pair := range in {
sum := pair[0] + pair[1]
if sum >= c && sum <= d {
out <- sum
}
}
}
func receiver(in <-chan int) {
line := 1
for sum := range in {
fmt.Printf("Line %d: Received sum %d\n", line, sum)
line++
}
}
func main() {
data1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
data2 := []int{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
data3 := []int{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
data4 := []int{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
c, d := 15, 50
senderToService := make(chan [2]int, 10)
serviceToReceiver := make(chan int, 10)
var wg sync.WaitGroup
// Start sender goroutines
wg.Add(4)
go sender(1, data1, senderToService, &wg)
go sender(2, data2, senderToService, &wg)
go sender(3, data3, senderToService, &wg)
go sender(4, data4, senderToService, &wg)
go func() {
wg.Wait()
close(senderToService)
}()
go service(senderToService, c, d, serviceToReceiver)
receiver(serviceToReceiver)
}
Upvotes: 4