Доступ к каналу из другой горутины

В настоящее время у меня есть следующий код:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

var channel = make(chan []float32, 1)

func main() {
    aMap := initMap()

    for key := range aMap {
        fmt.Print("the iteration number is: ", key)

        theSlice := aMap[key]
        channel <- theSlice
        go transition(channel)
        time.Sleep(2 * time.Second)

    }
}

func transition(channel chan []float32) {
    newSlice := make([]float32,5)
    newSlice = <- channel
    fmt.Println(newSlice)

    //need to retrieve the last element of the other slice and put it on this newSlice
}

func initMap() map[int][]float32 {
    aMap := make(map[int][]float32)
    for i := 0; i < 2; i++ {
        aMap[i] = []float32{rand.Float32(), rand.Float32(), rand.Float32(), rand.Float32(), rand.Float32()}
    }
    return aMap
}

У нас есть карта с двумя слайсами, и я пытаюсь взять последний элемент slice1 и сделать его последним элементом slice2 и наоборот.

На самом деле я работаю над более крупным проектом, который включает в себя моделирование деления и дифференцировки клеток. Поскольку это симуляция, все деления и дифференциации происходят одновременно. Проблема заключается в дифференцировке, когда клетка типа А трансформируется в клетку типа В. Каждый тип ячеек хранится в другой структуре данных, и я решил, что могу использовать один канал для каждой отдельной структуры данных и использовать каналы для одновременного изменения данных.

Надеюсь, это имеет смысл. Какие-либо предложения?

Спасибо, СиДжей

РЕДАКТИРОВАТЬ: кажется, что я спрашиваю, не ясно. Мой вопрос для приведенного выше примера: как я могу одновременно менять последние элементы каждого из двух фрагментов?


person sSmacKk    schedule 01.05.2014    source источник
comment
я добавил редактирование, которое разъясняет, что я прошу. Спасибо   -  person sSmacKk    schedule 01.05.2014


Ответы (1)


Каналы двусторонние и предназначены для общения, а не для совместного использования памяти. Поэтому, возможно, вместо того, чтобы отправлять весь слайс, просто отправьте последний элемент в каждом слайсе в одном направлении по каналу, а затем отправьте второе значение обратно в другом направлении.

  func main() {

    ...
    // send only the last item
    theSlice := aMap[key]
    channel <- theSlice[len(theSlice)-1]
    // waiting for the response
    theSlice[len(theSlice)-1] = <- channel
  }

  func transition(channel chan []float32) {
    newSlice := make([]float32,5)
    channel <- newSlice[len(newSlice)-1]
    newSlice[len(newSlice)-1] = <- channel
    fmt.Println(newSlice)
 }

Приведенный выше код предполагает, что объявление канала было изменено со среза на просто float32:

 var channel = make(chan float32, 1)
person miltonb    schedule 01.05.2014
comment
спасибо, имеет смысл для небольшого примера, который я дал. но представьте, что у нас было более двух срезов, я не верю, что этот двухсторонний подход сработает... - person sSmacKk; 01.05.2014
comment
BTW: Должен признаться, я не компилировал вышеизложенное, так что где-то может быть опечатка. - person miltonb; 01.05.2014
comment
Есть отличное выступление Роба Пайка, в котором рассказывается о разветвлениях и разветвлениях каналов. talks.golang.org/2012/concurrency.slide. В нем есть несколько отличных примеров шаблонов параллелизма, которые стоит изучить. - person miltonb; 01.05.2014