在GOLANG中,有一种简单的方法可以跨通道为多态行为转换结构吗?我试图在一个通道上发送不同版本的结构,所以例如我将有不同类型的事件,比如LoginEvent.每个结构中都有不同数量的数据.
package main
import "fmt"
type Event struct {
EvtType EvtType
Username string
Data string
}
type LoginEvent struct {
Event
CallBackChannel chan *Event
}
type EvtType int
const (
Login EvtType = iota+1
Logout
ChatMessage
Presense
BuddyList
)
func main() {
fakeOutputChan := make(chan<- *Event)
ourSrvChannel := make(chan *Event)
lg := (LoginEvent{Event{Login,"",""} ,ourSrvChannel})
fakeOutputChan <- (*Event)(&lg)
fmt.Println("Hello, playground")
}
Run Code Online (Sandbox Code Playgroud) 我们有一个WCF服务,我们正在从Web应用程序中消费.我们使用的客户端是使用Visual Studio"添加服务引用"选项生成的.由于它是一个Web应用程序,并且由于应用程序的性质可能会导致相对较短的会话,因此我们选择在用户登录时创建客户端实例并在会话期间保留它,然后处理会话时处理它.
这让我想到了一个问题 - 我们正试图决定处理客户进入故障状态的渠道的最佳方法.在搜索了一些之后,我们想出了这个:
if(client.State = CommuncationState.Faulted)
{
client = new Client();
}
try
{
client.SomeMethod();
}
catch //specific exceptions left out for brevity
{
//logging or whatever we decide to do
throw;
}
Run Code Online (Sandbox Code Playgroud)
然而,由于至少在我们的情况下,即使服务停止,客户端将显示Open状态,直到您实际尝试使用它进行呼叫,此时它进入Faulted状态这一事实不起作用..
所以这让我们做了别的事情.我们提出的另一个选择是:
try
{
client.SomeMethod();
}
catch
{
if(client.State == CommunicationState.Faulted)
{
//we know we're faulted, try it again
client = new Client();
try
{
client.SomeMethod();
}
catch
{
throw;
}
}
//handle other exceptions
}
Run Code Online (Sandbox Code Playgroud)
但那闻起来.显然,我们可以通过使用新客户端并为每次调用处理它来避免这种情况.这似乎是不必要的,但如果这是正确的方式,那么我猜这是我们会选择的.那么,优雅地处理确定客户端是否处于故障状态然后对其进行某些操作的最佳方法是什么?我们真的应该为每次通话获得新客户吗?
另外要记住的一点是 - 客户端的实例化以及所有这些检查和处理都发生在客户端的包装类中.如果我们按照我们的预期方式执行此操作,它对应用程序本身是透明的 - …
我想知道这个着名的引言最真实的解释是什么:
不要通过共享内存进行通信; 通过沟通分享记忆.(R. Pike)
在Go Go Memory Model中,我可以读到:
通道上的发送在该通道的相应接收完成之前发生.(Golang Spec)
还有一篇专门的golang文章解释了这句话.而关键的贡献也是Andrew G.的一个实例.
好.有时太多谈论....我从Memory Spec报价中得出,并且通过查看工作示例:
在goroutine1通过通道向goroutine2发送(任何内容)后,goroutine1完成的所有更改(内存中的任何位置)必须在通过相同通道接收到goroutine2后才可见.(Golang Lemma by Me :)
因此,我得出了着名引言的脚踏实地的解释:
要同步两个goroutine之间的内存访问,您不需要通过通道发送该内存.足够好的是从频道接收(甚至没有).您将看到goroutine发送(到频道)时发送的任何更改(在任何地方).(当然,假设没有其他goroutine写入相同的内存.)更新(2)8-26-2017
我实际上有两个问题:
1)我的结论是否正确?
2)我的解释有帮助吗?
更新(1) 我假设没有缓冲的频道.让我们首先限制自己,避免用太多的未知数来改造自己.
请注意,我们还要关注两个goroutine的简单用法,这两个goroutines通过单个通道和相关的记忆效应进行通信而不是最佳实践 - 这超出了本问题的范围.
为了更好地理解我的问题的范围,假设goroutine可以访问任何类型的内存结构 - 不仅是原始的 - 并且它可以是一个大的,它可以是字符串,映射,数组,等等.
在我的C#(3.5)应用程序中,我需要获取位图的红色,绿色和蓝色通道的平均颜色值.最好不使用外部库.可以这样做吗?如果是这样,怎么样?提前致谢.
尝试使事情更精确:位图中的每个像素都有一定的RGB颜色值.我想获得图像中所有像素的平均RGB值.
我试图弄清楚如何通过一个通道发送一个函数,以及如何避免额外的克隆,以便在另一端执行该函数.如果我在闭包内删除额外的克隆操作,我会收到以下错误:
error: cannot move out of captured outer variable in an 'Fn' closure
Run Code Online (Sandbox Code Playgroud)
忽略这个代码绝对没有任何东西,并使用全局可变静态这一事实Sender<T>,它代表了我正在尝试实现的同时给出正确的编译器错误.这段代码不打算运行,只是编译.
use std::ops::DerefMut;
use std::sync::{Arc, Mutex};
use std::collections::LinkedList;
use std::sync::mpsc::{Sender, Receiver};
type SafeList = Arc<Mutex<LinkedList<u8>>>;
type SendableFn = Arc<Mutex<(Fn() + Send + Sync + 'static)>>;
static mut tx: *mut Sender<SendableFn> = 0 as *mut Sender<SendableFn>;
fn main() {
let list: SafeList = Arc::new(Mutex::new(LinkedList::new()));
loop {
let t_list = list.clone();
run(move || {
foo(t_list.clone());
});
}
}
fn run<T: Fn() + Send + Sync …Run Code Online (Sandbox Code Playgroud) 在Golang中,如果某个频道channel已关闭,我仍然可以使用以下语法从中读取它,我可以测试ok它是否已关闭.
value, ok := <- channel
if !ok {
// channel was closed and drained
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我不知道某个频道是否已关闭并盲目写入,我可能会收到错误.我想知道是否有任何方法可以测试通道,只有当它没有关闭时才写入它.我问这个问题是因为有时候我不知道goroutine中是否关闭了一个频道.
使用PHP的PEAR,如何检查foo通道中的包是否bar已安装?(假设该频道bar可用,并且已被"发现".)这样的东西只pear list显示在频道中安装的包bar将是理想的.
我想找到一个队列结构(数据容器),其元素必须先进先出.对我来说重要的是结构必须是线程安全的.我将使用此数据容器作为任务或连接池.
我知道缓冲通道是线程安全的,但我不知道它是否作为FIFO工作,尤其是在并发情况下.
如果可以将缓冲通道用作线程安全队列,我是否需要担心其效率?
对于我的一个要求,我必须创建N个工作进程例程,这将由一个监视例程监视.当所有工作程序完成时,监视例程必须结束.我的代码以死锁结束,请帮忙.
import "fmt"
import "sync"
import "strconv"
func worker(wg *sync.WaitGroup, cs chan string, i int ){
defer wg.Done()
cs<-"worker"+strconv.Itoa(i)
}
func monitorWorker(wg *sync.WaitGroup, cs chan string) {
defer wg.Done()
for i:= range cs {
fmt.Println(i)
}
}
func main() {
wg := &sync.WaitGroup{}
cs := make(chan string)
for i:=0;i<10;i++{
wg.Add(1)
go worker(wg,cs,i)
}
wg.Add(1)
go monitorWorker(wg,cs)
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud) 我正在使用带有core.async的Clojure,并且我希望对通过通道处理的消息数量设置速率限制.
特别是我想:
实现这一目标的最佳方法是什么?