我是一名来自波兰的学生,这学期我开始了并发编程课程(Go、Ada 以及将来的一些理论和 CSP 语言)。说实话,Golang 看起来很有趣,但我对并发有点困惑,所有的等待组,互斥体等。最重要的是,根据我的经验,我称自己为低于平均水平的程序员。基本上,我的任务是创建一个模拟,我将这样描述:
-> 有一个 n*m 网格-
可以随机产生旅行者,最多 k 个旅行者,每个旅行者都有唯一的 ID(1、2、3 等等,最多 k 个)
-> 在随机时刻,如果空间是空闲的,旅行者可以在网格上向上、向左、向右或向下移动(我确定可用空间为 0)
-> 还有一个摄像头,有时会打印网格的当前状态以及最近的移动(尚未实现)
-> 非官方的,我听说我应该使用频道,无论这意味着什么
我的想法是制作一个带有 id 和每个旅行者坐标的结构,并将他们的 id 发送到表示移动意愿的通道,然后我会随机选择移动方向。
我对并发有点困惑 - 不仅是我是否以及在哪里应该使用 wgs 和互斥体,而且例如,如果我执行 go func(){} 循环应该在内部还是外部。我将非常感激提示、帮助或修复/想法来修复我的代码,因为目前,正如您所猜测的,它无法正常工作(例如,当相机打印网格时,有时有超过 k 名旅行者,其中多个旅行者共享相同的号码,有时他们似乎消失了)。希望每个人都有美好的一天,我真的很感激任何帮助:)
package main;
import(
"fmt"
"os"
"strconv"
"math/rand"
//"sync"
"time"
)
type traveler struct{
id int;
x int;
y int;
}
func main(){
//command line
n, err := strconv.Atoi(os.Args[1]);
m, err := strconv.Atoi(os.Args[2]);
k, err := strconv.Atoi(os.Args[3]);
if err != nil{
panic(err)
return
}
//board
var grid [][]int;
grid = make([][]int, n)
for i:=0; i<n; i++{
grid[i] = make([]int, m)
}
//array of travelers, channel for moves and id
travelers := make([]traveler, k)
no_of_travelers := 0;
move := make(chan int, k);
id := 1;
//var wg sync.WaitGroup
go camera(grid);
go func() {
for i:=0; i<len(travelers); i++ {
if no_of_travelers<k{
travelers[i] = spawnTraveler(&id,grid);
no_of_travelers++;
}
}
}()
go func() {
for{
a:= rand.Intn(k);
sendMoveTraveler(&travelers[a], move);
}
}()
receiveMoveTraveler(travelers, move, grid);
}
func spawnTraveler(id *int, grid [][]int) traveler{
x:=-1;
y:=-1;
for{
x = rand.Intn(len(grid));
y = rand.Intn(len(grid));
if(grid[x][y]==0){
break;
}
}
t := traveler{id: *id, x: x, y:y};
grid[x][y] = *id;
*id++;
return t;
}
func sendMoveTraveler(t *traveler, move chan int){
move <- t.id
}
func receiveMoveTraveler(travelers []traveler, move chan int, grid [][]int){
for{
id := <- move
for i:=0; i<len(travelers); i++{
if travelers[i].id == id{
direction := rand.Intn(4); //1-left 2-up 3-right 4-down
switch direction {
case 0:
if travelers[i].x>0 && grid[travelers[i].x-1][travelers[i].y] == 0{
grid[travelers[i].x-1][travelers[i].y] = grid[travelers[i].x][travelers[i].y];
grid[travelers[i].x][travelers[i].y] = 0;
travelers[i].x = travelers[i].x-1;
travelers[i].y = travelers[i].y;
}
case 1:
if travelers[i].y>0 && grid[travelers[i].x][travelers[i].y-1] == 0{
grid[travelers[i].x][travelers[i].y-1] = grid[travelers[i].x][travelers[i].y];
grid[travelers[i].x][travelers[i].y] = 0;
travelers[i].x = travelers[i].x;
travelers[i].y = travelers[i].y-1;
}
case 2:
if travelers[i].x<len(grid)-1 && grid[travelers[i].x+1][travelers[i].y] == 0{
grid[travelers[i].x+1][travelers[i].y] = grid[travelers[i].x][travelers[i].y];
grid[travelers[i].x][travelers[i].y] = 0;
travelers[i].x = travelers[i].x+1;
travelers[i].y = travelers[i].y;
}
case 3:
if travelers[i].y<len(grid)-1 && grid[travelers[i].x][travelers[i].y+1] == 0{
grid[travelers[i].x][travelers[i].y+1] = grid[travelers[i].x][travelers[i].y];
grid[travelers[i].x][travelers[i].y] = 0;
travelers[i].x = travelers[i].x;
travelers[i].y = travelers[i].y+1;
}
}
//fmt.Println("Ściagnalem ruch", travelers[i].id);
}
}
}
}
func camera(grid [][]int){
for{
for i:=0; i<len(grid); i++{
for j:=0; j<len(grid); j++{
if grid[i][j]!= 0{
fmt.Printf("%02d ", grid[i][j]);
} else{
fmt.Printf("-- ");
}
}
fmt.Println();
}
fmt.Println();
time.Sleep(time.Second * 3);
}
}
所有的想法都让我有点不知所措——wgs、互斥体、原子等。
话虽这么说: