Go博客中的" Go maps in action "条目指出:
映射对于并发使用是不安全的:它没有定义当您同时读取和写入时会发生什么.如果您需要从同时执行的goroutine中读取和写入映射,则访问必须由某种同步机制调解.保护地图的一种常用方法是使用sync.RWMutex.
但是,访问映射的一种常用方法是使用range
关键字迭代它们.目前尚不清楚,为了并发访问的目的,range
循环内的执行是"读",还是只是该循环的"周转"阶段.例如,以下代码可能会或可能不会与"无并发r/w映射"规则相冲突,具体取决于操作的特定语义/实现range
:
var testMap map[int]int
testMapLock := make(chan bool, 1)
testMapLock <- true
testMapSequence := 0
Run Code Online (Sandbox Code Playgroud)
...
func WriteTestMap(k, v int) {
<-testMapLock
testMap[k] = v
testMapSequence++
testMapLock<-true
}
func IterateMapKeys(iteratorChannel chan int) error {
<-testMapLock
defer func() {
testMapLock <- true
}
mySeq := testMapSequence
for k, _ := range testMap {
testMapLock <- true
iteratorChannel <- k
<-testMapLock
if mySeq != testMapSequence {
close(iteratorChannel)
return errors.New("concurrent …
Run Code Online (Sandbox Code Playgroud) 看着net.TCPListener
。考虑到 Go 并发范例,人们会期望将此系统功能实现为通道,以便您chan *net.Conn
从Listen()
函数或类似的东西中获得 a 。
但看起来 Accept() 就是这样,而且只是阻塞,就像系统接受一样。除了它是残废的,因为:
所以我正在做类似的事情:
acceptChannel = make(chan *Connection)
go func() {
for {
rw, err := listener.Accept()
if err != nil { ... handle error ... close(acceptChannel) ... return }
s.acceptChannel <-&Connection{tcpConn: rw, .... }
}
}()
Run Code Online (Sandbox Code Playgroud)
这样我就可以在选择中使用多个服务器套接字,或者将 Accept() 上的等待与其他通道复用。我错过了什么吗?我是 Go 的新手,所以我可能会忽略一些事情 - 但 Go 真的没有用自己的并发范例实现自己的阻塞系统功能吗?我真的需要为每个我想监听的套接字(可能是数百个或数千个)使用一个单独的 goroutine 吗?这是使用正确的习惯用法,还是有更好的方法?
我试图按照这里的说明构建一个简单的操作系统内核:http://mikeos.sourceforge.net/write-your-own-os.html
除了从软盘启动,我想创建一个基于grub的ISO映像并在模拟器中启动多重启动CD.对于多引导头,我已将以下内容添加到该页面上列出的源:
MBALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum of above, to prove we are multiboot
section .multiboot
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
Run Code Online (Sandbox Code Playgroud)
我正在做以下事情来创建图像:
nasm -felf32 -o init.bin init.s
cp init.bin target/boot/init.bin
grub2-mkrescue -o …
Run Code Online (Sandbox Code Playgroud) 是否有可能以一种简单的方式来做相当于Java的工作
wait(long timeMillis)
Run Code Online (Sandbox Code Playgroud)
在指定的时间内在监视器上(互斥锁+ cond,粗略地)等待,如果没有信号则返回?
我在文档中找不到任何东西或在谷歌上搜索,虽然它当然可以通过制作一个WaitGroup和定时器goroutine pop来玩一些游戏,但这似乎很乏味/烦人/低效才能获得这个简单的功能(这是我遇到的任何底层系统线程库直接支持的方式)
编辑:是的我们都阅读了http://www.golang-book.com/10/index.htm以及https://blog.golang.org/pipelines - 再次,创建更多线程是一个"坏"(非性能的解决方案,并且渠道也不太适合这个.想象一个用例是一个典型的并发服务器Join()方法......(请不要告诉我反转控件并使用一个Listener模式.你并不总是可以更改你正在使用的API. ..)
我现在的情况与此线程中的问题相同: 具有嵌入式匿名接口的结构的含义?
type A interface {
Foo() string
}
type B struct {
A
bar string
}
Run Code Online (Sandbox Code Playgroud)
习惯上,来自OOP语言的背景,看起来这种模式对我来说"试图说"是B必须实现接口A.但我现在已经知道"Go是不同的".所以,不是我最初预期的编译时检查,而是很高兴编译有或没有
func (B) Foo() string { .... }
Run Code Online (Sandbox Code Playgroud)
当下.正如上面的问题所指出的那样("释义"):"当你只想实现/部分/接口时,在结构中使用嵌入式接口非常有用".
据推测,这是因为此嵌入所发生的事情与其他情况一样 - 类型B的值将具有类型A的匿名接口值,作为字段.就个人而言,当我发现正交性安慰时,我也发现令人困惑的是反射包然后让我直接从B的类型获得A的方法,而不是错误/ nil如果没有接收器B的方法存在.但是 - 这个问题不是关于背后的想法 - 它是关于如何在b := B{}
以下情况下初始化接口值:
func main() {
bType := reflect.TypeOf(B{})
bMeth, has := bType.MethodByName("Foo")
if has {
fmt.Printf("HAS IT: %s\n",bMeth.Type.Kind())
res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
val := res[0].Interface()
fmt.Println(val)
} else {
fmt.Println("DOESNT HAS IT")
}
}
Run Code Online (Sandbox Code Playgroud)
当它运行时,它会引起可怕的恐慌
HAS IT: func
panic: runtime error: invalid memory address or …
Run Code Online (Sandbox Code Playgroud) 我正在尝试找到一种在uint64_t
不支持 128 位整数的系统上使用 C 实现 EEA 的方法。问题在于,似乎总是存在某些变量会溢出的情况,从而产生不正确的结果。
我知道它可以用 /signed/ 机器字来完成,并且这里和其他地方有很多答案给出了伪代码。可以用无符号且无溢出来完成吗?或者您是否需要更大的可用整数大小?
reflect.StructField
有一个Index
键入的字段[]int
。关于此的文档有点令人困惑:
Index []int // index sequence for Type.FieldByIndex
Run Code Online (Sandbox Code Playgroud)
当然,Type.FieldByIndex
正如预期的那样,对其行为有更清晰的解释:
// FieldByIndex returns the nested field corresponding
// to the index sequence. It is equivalent to calling Field
// successively for each index i.
// It panics if the type's Kind is not Struct.
FieldByIndex(index []int) StructField
Run Code Online (Sandbox Code Playgroud)
但是,还有Type.Field()
:
// Field returns a struct type's i'th field.
// It panics if the type's Kind is not Struct.
// It panics if i is …
Run Code Online (Sandbox Code Playgroud) 我正在尝试在 go 中进行简单的 YAML 解析gopkg.in/yaml.v2
。
从文档中:
映射和指针(指向结构、字符串、int 等)被接受为输出值。如果结构中的内部指针未初始化,则 yaml 包将在必要时对其进行初始化以解组所提供的数据。out 参数不能为 nil。
解码值的类型应与输出中的相应值兼容。如果由于类型不匹配而无法解码一个或多个值,则解码将继续部分进行,直到 YAML 内容结束,并返回一个 *yaml.TypeError ,其中包含所有丢失值的详细信息。
请注意此处的重要位:“如果 nec'y,则初始化结构内的指针”,以及“如果无法解码值,则返回 yaml.TypeError”。
现在:
包主
import (
"fmt"
"gopkg.in/yaml.v2"
)
type YamlTypeA struct {
D string `yaml: "d"`
E string `yaml: "e"`
}
type YamlTypeB struct {
F string `yaml: "f"`
}
type YamlTypeC struct {
TypeA *YamlTypeA `yaml: "a"`
TypeB []YamlTypeB `yaml: "b"`
}
func main() {
var yamlObj YamlTypeC
text := []byte(`
---
a:
d: foo
e: …
Run Code Online (Sandbox Code Playgroud) 按照doxygen手册中的示例,我构造了测试头test.h
:
/**
* @file test.h
*/
/** @brief This is a struct
* @var foo A foo.
* @var bar Also a Foo.
* @var baz (unused field)
*/
typedef struct {
int foo;
int bar;
char *baz;
} whatsit;
Run Code Online (Sandbox Code Playgroud)
当我使用默认值Doxyfile
(由'生成doxygen -g
)时,会看到警告:
... test.h:11:警告:未记录复合whatsit
... test.h:7:警告:未定义记录符号`foo A Foo`
... test.h:12:警告:未记录whatsit类的成员foo(变量)
是什么赋予了?我从手册中得到的印象是,您不需要标记,例如@struct
注释直接位于定义之前,并且在上面的块中记录成员var是合法的,而不是使用它们声明的相同行/*< ...
句法。(我绝对讨厌后者的风格...)
我该如何正确识别评论?
这是具有类似名称的先前线程的后续跟进.
它有一个公认的答案,但答案并没有真正回答这个问题.从该线程,这是用例:
if len(myChannel) > 0 {
// Possible issue here: length could have changed to 0 making this blocking
elm := <- myChannel
return elm
}
Run Code Online (Sandbox Code Playgroud)
OP称之为"可能的问题",但它是一个确定问题:一种竞争条件,其中另一个消费者可能在评估if条件和执行两个语句之间从通道中提取了一个值.
现在,我们被告知Go Way是支持频道而不是互斥,但是在这里我们似乎无法实现基本的非阻塞读取(通过轮询长度和原子读取)而无需将互斥锁和通道配对在一起,并使用我们的新并发数据类型而不是通道.
那可能是对的吗?是否真的没有办法可靠地确保recv不会通过提前检查空间来阻止?(与Java中的BlockingQueue.poll()或其他基于队列的消息传递IPC工具中的类似工具相比......)
这是一些代码.
function callServiceSync(url, obj) {
var result = true;
callServiceOptions(url, obj, function(res){
result = res;
alert("RESULT CB: "+JSON.stringify(result));
}, {async: false});
alert("RESULT POST-CB: "+JSON.stringify(result));
return result;
}
Run Code Online (Sandbox Code Playgroud)
运行时,警告框显示:
结果CB:{"成功":真实,"数据":"dtrombley"}
(这就是webservice实际返回的内容),然后:
结果POST-CB:是的
为什么闭包变量的赋值不起作用?我误解了JS闭包是如何工作的吗?
callServiceOptions()相当漫长 - 但它的要点是它调用jQuery的$ .ajax方法,它的最后一个参数选项扩展为某些默认值(在这种情况下,async禁用同步查询),然后执行提供的回调.
是$ .ajax()可能以某种方式执行某些禁用/搞砸闭包的方式(但我称之为cb,而不是$ .ajax()!)?如果是这样,如何解决?
为了完整性(虽然这个功能真的不应该让我的想法搞砸了):
function callServiceOptions(url, obj, cb, options) {
optSuccess = options.success;
optError = options.error;
opts = {}
$.extend({},options)
if (!opts.contentType) {
opts.contentType = "application/json";
}
if (!opts.dataType) {
opts.dataType = "json";
}
if (!opts.data && obj) {
opts.data = JSON.stringify(obj); …
Run Code Online (Sandbox Code Playgroud) 我想要一个match
具有相当长的 OR 模式的模式,例如:
match item:
case Really.Long.Qualified.Name.ONE | Really.Long.Qualified.Name.TWO | Really.Long.Qualified.Name.THREE | Some.Other.Patterns.Here:
pass
Run Code Online (Sandbox Code Playgroud)
这对于单行来说显然非常烦人。但是,PyCharm 似乎不会像往常一样警告长线,并且如果我使用换行符(即使它已转义),则会报告语法错误。
有什么方法可以更好地格式化此代码,或者整个模式必须在一行上?是否有明确的来源可以证明这一点 - 我在 PEP 中找不到它用于匹配/案例或特别是。
如果是后者,为什么要做出这样的语言设计决策?好像……不太好……
go ×7
concurrency ×3
c ×2
reflection ×2
ajax ×1
assembly ×1
dictionary ×1
doxygen ×1
embedding ×1
for-loop ×1
foreach ×1
grub ×1
interface ×1
javascript ×1
jquery ×1
kernel ×1
match ×1
osdev ×1
python ×1
sync ×1
synchronous ×1
tags ×1
tcp ×1
x86 ×1
yaml ×1