Jadual Kandungan
Kandungan soalan
Penyelesaian
Rumah pembangunan bahagian belakang Golang Simulasi Go yang mudah - isu konkurensi

Simulasi Go yang mudah - isu konkurensi

Feb 09, 2024 pm 02:10 PM
capaian data

Simulasi Go yang mudah - isu konkurensi

editor php Xinyi membawakan anda permainan simulasi Go yang ringkas tetapi menarik yang dipanggil "Masalah Concurrency". Permainan ini mengambil pengaturcaraan serentak sebagai temanya, membolehkan pemain mengalami daya tarikan pengaturcaraan serentak dalam dunia maya. Dalam permainan, pemain perlu menulis kod untuk mengendalikan pelaksanaan serentak pelbagai tugas dan menguji kebolehan pengaturcaraan serentak mereka. Antara muka permainan adalah ringkas dan jelas, dan operasinya mudah, sesuai untuk pemula untuk bermula, dan ia juga menyediakan pelbagai mod kesukaran dan cabaran untuk dipilih oleh pemain. Sama ada anda seorang pemula atau pembangun yang berpengalaman, anda boleh menikmati keseronokan pengaturcaraan serentak dalam permainan simulasi ini.

Kandungan soalan

Saya seorang pelajar dari Poland dan semester ini saya memulakan kursus pengaturcaraan serentak (Go, Ada dan beberapa bahasa teori dan CSP pada masa hadapan). Sejujurnya, Golang kelihatan menarik tetapi saya agak keliru. Kesimpulannya ialah dalam pengalaman saya, saya akan memanggil diri saya seorang pengaturcara di bawah purata. Pada asasnya, tugas saya adalah untuk mencipta simulasi, yang akan saya huraikan seperti ini:

  • Terdapat grid n*m

  • Pengembara boleh dijana secara rawak, sehingga k pengembara, setiap pengembara mempunyai ID unik (1, 2, 3, dsb., sehingga k)

  • Secara rawak, jika ruang kosong (saya pasti ruang kosong ialah 0), pengembara boleh bergerak ke atas, kiri, kanan atau bawah pada grid

  • Juga mempunyai kamera yang kadangkala mencetak keadaan semasa mesh serta pergerakan terkini (belum dilaksanakan)

  • Secara tidak rasmi, saya pernah dengar saya patut menggunakan saluran, apa pun maksudnya

Idea saya adalah untuk mencipta struktur dengan id dan koordinat setiap pengembara dan menghantar id mereka ke saluran yang mewakili kesediaan untuk bergerak, dan kemudian saya akan memilih arah pergerakan secara rawak.

Saya agak keliru tentang concurrency - bukan sahaja jika dan di mana saya harus menggunakan wgs dan mutex, tetapi juga sebagai contoh jika saya pergi func(){} sekiranya gelung berada di dalam atau di luar. Saya amat berbesar hati untuk menghargai sebarang petua, bantuan atau pembetulan/idea untuk membetulkan kod saya kerana pada masa ini, seperti yang anda sangka, ia tidak berfungsi dengan betul (cth. apabila kamera mencetak grid, kadangkala terdapat lebih daripada k pengembara , di mana berbilang pengembara berkongsi nombor yang sama dan kadangkala mereka kelihatan hilang). Harap semua orang mempunyai hari yang hebat dan saya sangat menghargai sebarang bantuan :)

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);
}
}
Salin selepas log masuk

Saya agak terharu dengan semua idea - wg, mutex, atom, dll.

Penyelesaian

  • Jika anda ingin memproses kerja secara serentak (cth. mengambil syot kilat kamera dan menggerakkan pengembara boleh berlaku pada masa yang sama), goroutine ialah benang yang ringan.
  • Saluran digunakan untuk memindahkan data antara rutin Go.
  • Mutex digunakan untuk membenarkan gorout menambah kunci pada data kongsi untuk akses data eksklusif bagi mengelakkan keadaan perlumbaan.

Bahawa dikatakan:

  • Menjalankan syot kilat kamera dalam satu goroutine sambil meminta pengembara bergerak dalam goroutine lain kelihatan bagus. Melahirkan Goroutine adalah tidak perlu, anda hanya perlu melakukannya sekali, supaya anda boleh melaksanakannya dalam Goroutine utama.
  • Dalam kes anda, saluran tidak membawa manfaat. Anda mempunyai Goroutine yang menjana mesej dan menghantarnya melalui saluran ke Goroutine lain yang akan melakukan pergerakan. Anda boleh melakukan semua ini secara berurutan dalam satu goroutine dan mengelakkan kerumitan yang tidak perlu. Saluran berguna untuk kes penggunaan yang berbeza, tetapi di sini ia adalah berlebihan.
  • Memandangkan anda mempunyai dua gorout mengakses memori kongsi (grid), anda memerlukan mutex untuk mengelakkan keadaan perlumbaan. Setiap kali salah satu daripada ini dijalankan, ia mesti "mengunci", menyelesaikan kerjanya, dan kemudian "membuka kunci". Satu lagi goroutine akan menyekat pada langkah penguncian sehingga goroutine pertama yang memperoleh kunci itu terbuka. Anda boleh mengoptimumkannya lagi menggunakan kunci baca/tulis (kunci baca hanya diperlukan untuk kamera dan kunci baca/tulis untuk coroutine mudah alih)
  • Jika anda mahukan lebih rawak, anda boleh membuat goroutine untuk setiap pengembara.

Atas ialah kandungan terperinci Simulasi Go yang mudah - isu konkurensi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Apakah maksud dao dalam java Apakah maksud dao dalam java Apr 21, 2024 am 02:08 AM

DAO (Data Access Object) dalam Java digunakan untuk memisahkan kod aplikasi dan lapisan kegigihan, kelebihannya termasuk: Pemisahan: Bebas daripada logik aplikasi, menjadikannya mudah untuk mengubah suainya. Enkapsulasi: Sembunyikan butiran akses pangkalan data dan mudahkan interaksi dengan pangkalan data. Kebolehskalaan: Mudah dikembangkan untuk menyokong pangkalan data baharu atau teknologi kegigihan. Dengan DAO, aplikasi boleh memanggil kaedah untuk melaksanakan operasi pangkalan data seperti mencipta, membaca, mengemas kini dan memadam entiti tanpa berurusan secara langsung dengan butiran pangkalan data.

I7-13620h gred apa? I7-13620h gred apa? Apr 15, 2024 pm 04:30 PM

Saya percaya anda telah melihat bahawa antara produk terbaru yang diumumkan oleh Mechanic, terdapat model terbaru i7-13620h. Jadi, apa yang semua orang ingin tahu ialah, i7-13620h gred apa? i7-13620h ialah pemproses berprestasi tinggi, tergolong dalam julat pertengahan hingga tinggi. Ia menggunakan teknologi proses Intel, mempunyai 6 P-Core dan 8 E-Core, sejumlah 14 teras dan 20 benang, dengan frekuensi utama 2.6GHz, frekuensi teras maksimum 5.0GHz, dan dilengkapi dengan 96 set EU paparan teras Xe teras. i7-13620h mempunyai kapasiti cache yang besar, termasuk cache tahap tiga (L3Cache), yang boleh memberikan kelajuan capaian data yang lebih pantas dan mempercepatkan pemprosesan dan pengiraan data pemproses. percayakan awak

Satu kad menjalankan Llama 70B lebih pantas daripada dua kad, Microsoft hanya meletakkan FP6 ke dalam A100 | Satu kad menjalankan Llama 70B lebih pantas daripada dua kad, Microsoft hanya meletakkan FP6 ke dalam A100 | Apr 29, 2024 pm 04:55 PM

FP8 dan ketepatan pengiraan titik terapung yang lebih rendah bukan lagi "paten" H100! Lao Huang mahu semua orang menggunakan INT8/INT4, dan pasukan Microsoft DeepSpeed ​​​​memaksa diri mereka menjalankan FP6 pada A100 tanpa sokongan rasmi daripada Nvidia. Keputusan ujian menunjukkan bahawa kaedah baharu TC-FPx FP6 kuantisasi pada A100 adalah hampir atau kadangkala lebih pantas daripada INT4, dan mempunyai ketepatan yang lebih tinggi daripada yang terakhir. Selain itu, terdapat juga sokongan model besar hujung ke hujung, yang telah bersumberkan terbuka dan disepadukan ke dalam rangka kerja inferens pembelajaran mendalam seperti DeepSpeed. Keputusan ini juga mempunyai kesan serta-merta pada mempercepatkan model besar - di bawah rangka kerja ini, menggunakan satu kad untuk menjalankan Llama, daya pemprosesan adalah 2.65 kali lebih tinggi daripada dua kad. satu

Bagaimana untuk mengalih keluar perlindungan tulis cakera U Beberapa kaedah mudah dan berkesan boleh membantu anda melakukannya Bagaimana untuk mengalih keluar perlindungan tulis cakera U Beberapa kaedah mudah dan berkesan boleh membantu anda melakukannya May 02, 2024 am 09:04 AM

Cakera U ialah salah satu peranti storan yang biasa digunakan dalam kerja dan kehidupan harian kita, tetapi kadangkala kita menghadapi situasi di mana cakera U dilindungi tulis dan tidak boleh menulis data. Artikel ini akan memperkenalkan beberapa kaedah mudah dan berkesan untuk membantu anda mengalih keluar perlindungan tulis pemacu kilat USB dan memulihkan penggunaan biasa pemacu kilat USB. Bahan alatan: Versi sistem: Windows1020H2, macOS BigSur11.2.3 Model jenama: SanDisk UltraFlair USB3.0 pemacu denyar, Kingston DataTraveler100G3USB3.0 pemacu denyar Versi perisian: DiskGenius5.4.2.1239, ChipGenius4.19.1225 1. Periksa suis perlindungan tulis fizikal pemacu kilat USB pada beberapa pemacu kilat USB Direka dengan

Apakah maksud skema dalam mysql Apakah maksud skema dalam mysql May 01, 2024 pm 08:33 PM

Skema dalam MySQL ialah struktur logik yang digunakan untuk mengatur dan mengurus objek pangkalan data (seperti jadual, paparan) untuk memastikan ketekalan data, kawalan capaian data dan memudahkan reka bentuk pangkalan data. Fungsi Skema termasuk: 1. Organisasi data; 3. Kawalan capaian data;

Apakah antara muka API untuk? Apakah antara muka API untuk? Apr 23, 2024 pm 01:51 PM

Antara muka API ialah spesifikasi untuk interaksi antara komponen perisian dan digunakan untuk melaksanakan komunikasi dan pertukaran data antara aplikasi atau sistem yang berbeza. Antara muka API bertindak sebagai "penterjemah", menukar arahan pembangun ke dalam bahasa komputer supaya aplikasi boleh berfungsi bersama. Kelebihannya termasuk perkongsian data yang mudah, pembangunan yang dipermudahkan, prestasi yang lebih baik, keselamatan yang dipertingkatkan, produktiviti yang lebih baik dan kesalingoperasian.

Bagaimana untuk menyelesaikan masalah bahawa sistem pelayan tidak boleh dimasukkan? Bagaimana untuk menyelesaikan masalah bahawa sistem pelayan tidak boleh dimasukkan? Apr 16, 2024 pm 12:54 PM

Garis panduan untuk membetulkan ketidakbolehcapaian sistem pelayan termasuk: menyemak isu perkakasan (bekalan kuasa, kabel, kipas); mod selamat), alat pembaikan sistem;

Prinsip pelaksanaan cache Redis Prinsip pelaksanaan cache Redis Apr 19, 2024 pm 10:36 PM

Mekanisme caching Redis dilaksanakan melalui storan nilai kunci, storan memori, dasar tamat tempoh, struktur data, replikasi dan kegigihan. Ia mengikuti langkah-langkah mendapatkan data, cache hit, cache miss, menulis ke cache dan mengemas kini cache untuk menyediakan akses data pantas dan perkhidmatan caching berprestasi tinggi.

See all articles