我遇到了一个特殊的问题,不幸的是,我无法在一个最小的工作示例中重现该问题。我会尽力解释,希望您至少能给我一些提示。
我有两个协议: A 和 B 。对于每种协议,只有一个中央方 p1 ,而三个外部方则称为那些 pn 。每一方都是作为单独的goroutine实现的。
协议 A 如下:
*big.Int
的结果发送到 p1 。*DecryptionShare
的结果发送到 p1 。*big.Int
。为此,我有三个渠道,一个用于发送数据 p1 -> pn ,一个用于 pn -> p1 和一个将最终结果输出回主线程(所有 pn 都从相同的通道读取和写入)。尽管 pn 的结果1.和3.具有不同的类型,所以通道类型为interface{}
。
协议 B 首先启动协议 A ,然后执行不相关的进一步计算。
这是我的问题:
协议 A 本身没有出现任何问题。 但是,当我打电话给 B 的运行次数约为10%时,即使 B 传递了唯一的区别,它也会惊恐于 A 。将参数输入 A 。
显示的错误是
panic: interface conversion: interface {} is *big.Int, not *DecryptionShare
暗示 p1 在第4步时收到*big.Int
,尽管它在第2步中已经收到了各方*big.Int
。
我尝试使用time.Sleep
和select
停留在步骤2更长的时间,但在该步骤中我再也没有得到额外的*big.Int
,它只是偶尔出现在步骤4中。 / p>
如果我不是使用chan interface{}
而不是使用两个单独的通道chan *big.Int
和chan *DecryptionShare
协议,则 B 正确终止,这也意味着从通道(ei没有线程被阻塞)。我希望避免这种情况,因为我已经在使用许多频道。
有人对为什么发生这种恐慌有任何想法吗?
编辑:
这是一个最小的工作示例,但是不会产生错误。希望它能获得一些见识。 *DecryptionShare
替换为int
。
package tpsi
import (
"math/big"
"fmt"
"crypto/rand"
"testing"
)
type DecryptionShare struct {
index int
p *big.Int
}
func TestErs(t *testing.T) {
message_channel1 := make(chan interface{})
message_channel2 := make(chan []*big.Int)
return_channel := make(chan *big.Int)
n := 4
go CentralParty(n, message_channel2, message_channel1, return_channel)
for i := 1; i < n; i += 1 {
go OtherParty(message_channel1, message_channel2, return_channel)
}
for i := 0; i < n; i += 1 {
fmt.Println(<-return_channel)
}
t.Error("for display")
}
func CentralParty(n int, sender_channel chan<- []*big.Int, reciever_channel <-chan interface{}, return_channel chan<- *big.Int) {
p, err := rand.Prime(rand.Reader, 256)
if err != nil {panic(err)}
all_p := make([]*big.Int, n)
all_p[0] = p
for i := 1; i < n; i += 1 {
all_p[i] = (<-reciever_channel).(*big.Int)
}
for i := 1; i < n; i += 1 {
sender_channel <- all_p
}
shares := make([]*DecryptionShare, 4)
for i := 1; i < n; i += 1 {
shares[i] = (<-reciever_channel).(*DecryptionShare)
}
return_channel <- shares[1].p
}
func OtherParty(sender_channel chan<- interface{}, reciever_channel <-chan []*big.Int, return_channel chan<- *big.Int) {
p, err := rand.Prime(rand.Reader, 256)
if err != nil {panic(err)}
sender_channel <- p
all_p := <-reciever_channel
var ds DecryptionShare
ds.p = p
ds.index = all_p[0].BitLen()
sender_channel <- &ds
return_channel <- p
}
答案 0 :(得分:0)
在几位评论员的共同压力下,我强迫自己获得MWE。而且正如@oakad所建议的那样,我在这样做时发现了该错误。
错误(毫无意外)来自协议 B ,该协议重用了chan interface{}
,并再次发送了第一个数据类型*big.Int
,从而引入了竞争条件。
我完全忽略了考虑各种协议的比赛条件。
谢谢您的评论!