小编noh*_*hup的帖子

优化golang中的数据结构/字对齐填充

与我在C++中学到的相似,我认为填充会导致两个结构的实例大小不同.

type Foo struct {
    w byte //1 byte
    x byte //1 byte
    y uint64 //8 bytes
}
type Bar struct {
    x byte //1 byte
    y uint64 //8 bytes
    w byte// 1 byte
}
func main() {
    fmt.Println(runtime.GOARCH)
    newFoo := new(Foo)
    fmt.Println(unsafe.Sizeof(*newFoo))
    newBar := new(Bar)
    fmt.Println(unsafe.Sizeof(*newBar))
}
Run Code Online (Sandbox Code Playgroud)

输出:

amd64
16
24
Run Code Online (Sandbox Code Playgroud)
  • 在定义struct成员时是否遵循经验法则?(如类型大小的升序/降序)
  • 是否有我们可以通过的编译时优化,可以自动处理这个?
  • 或者我不应该担心这一点?

struct padding go memory-alignment

11
推荐指数
2
解决办法
2998
查看次数

在Java中初始化变量的不同方法

我遇到了代码guessgame.有一个代码片段,其中三个播放器对象按以下方式初始化:

public class guessgame{
    Player p1;
    Player p2;
    Player p3;
    public void startGame() {
        p1 = new Player();
        p2 = new Player();
        p3 = new Player();
    ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

当我宣布并以下列方式发起时,同样有效.

public class GuessGame {
    Player p1 = new Player();
    Player p2 = new Player();
    Player p3 = new Player();
    public void startGame(){
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这两者有区别吗?在第一个例子中,为什么在startgame()方法之外声明了三个实例变量,它在内部真的很重要吗?

java

10
推荐指数
2
解决办法
6769
查看次数

在C中,我们可以在没有忙碌的情况下从管道中读取,可能正在使用回调或其他方式吗?

我试图从分叉过程的STDOUT中读取.但是,如果我正在无限地从管道读取,for loop即使没有数据通过管道也会忙着等待(如果我错了请纠正我),我想必须有更好的方法来做其他事情比使用sleep,如果它是短的间隔,可能是回调,这我不知道.以下是我尝试过的代码片段.

pid_t pid = fork();  
switch (pid) {
    case 0:
        dup2 (pipes[1], STDOUT_FILENO );
        dup2(pipes[1], STDERR_FILENO); 
        close(pipes[0]); 
        close(pipes[1]);
        execv(path, args);
        break;
    default :
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        child_pid = pid;
        signal(SIGHUP, mysighandle);
        close(pipes[1]); 
        ssize_t nbytes;
        for (;;) {
            nbytes = read(pipes[0], buf, BUFSIZE); 
            if (nbytes == -1){
                break;
            }
            if (nbytes == 0) {
                break;
            }
            syslog(LOG_NOTICE, "%s", buf);
Run Code Online (Sandbox Code Playgroud)

有人可以建议一个没有忙碌的更好的方法,可以用来从管道读取数据吗?由于我是初学者C,所以对代码片段的任何引用都很受欢迎.

问候.

c pipe busy-waiting

10
推荐指数
1
解决办法
557
查看次数

为什么在每次运行而不是固定数量的堆栈使用量不同时发生堆栈溢出?

我在Debian OS上运行一个带递归调用的程序.我的堆栈大小是

-s: stack size (kbytes)             8192
Run Code Online (Sandbox Code Playgroud)

据我所知,堆栈大小必须是固定的,并且必须与每次运行时必须分配给程序的相同,除非明确更改它ulimit.

递归函数是递减给定的数字,直到达到0.这是用Rust写的.

fn print_till_zero(x: &mut i32) {
    *x -= 1;
    println!("Variable is {}", *x);
    while *x != 0 {
        print_till_zero(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

并且值传递为

static mut Y: i32 = 999999999;
unsafe {
    print_till_zero(&mut Y);
}
Run Code Online (Sandbox Code Playgroud)

由于分配给程序的堆栈是固定的,理论上不能改变,我每次都希望堆栈溢出的值相同,但不是,这意味着堆栈分配是可变的.

运行1:

====snip====
Variable is 999895412
Variable is 999895411

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Run Code Online (Sandbox Code Playgroud)

运行2:

====snip====
Variable is 999895352
Variable is 999895351

thread 'main' has overflowed its stack
fatal …
Run Code Online (Sandbox Code Playgroud)

c linux stack-overflow out-of-memory rust

9
推荐指数
1
解决办法
280
查看次数

golang os*File.Readdir在所有文件上使用lstat.可以优化吗?

我正在编写一个程序,它从父目录中查找包含大量文件的所有子目录os.File.Readdir,但运行一个strace查看系统调用的计数表明go版本使用的lstat()是所有文件/目录.父目录.(我现在用/usr/bin目录测试这个)

去代码:

package main
import (
        "fmt"
    "os"
)
func main() {
    x, err := os.Open("/usr/bin")
    if err != nil {
        panic(err)
    }
    y, err := x.Readdir(0)
    if err != nil {
        panic(err)
    }
    for _, i := range y {
    fmt.Println(i)
    }

}
Run Code Online (Sandbox Code Playgroud)

程序上的Strace(没有跟随线程):

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 93.62    0.004110           2      2466           write
  3.46    0.000152           7        22           getdents64
  2.92    0.000128           0      2466 …
Run Code Online (Sandbox Code Playgroud)

c linux filesystems go stat

7
推荐指数
1
解决办法
622
查看次数

Python Multiprocessing并发使用Manager,Pool和共享列表不起作用

我正在学习python多处理,我正在尝试使用此功能来填充包含操作系统中所有文件的列表.但是,我写的代码只是按顺序执行.

#!/usr/bin/python
import os
import multiprocessing
tld = [os.path.join("/", f) for f in os.walk("/").next()[1]] #Gets a top level directory names inside "/"
manager = multiprocessing.Manager()
files = manager.list()


def get_files(x):
    for root, dir, file in os.walk(x):
        for name in file:
            files.append(os.path.join(root, name))

mp = [multiprocessing.Process(target=get_files, args=(tld[x],))
      for x in range(len(tld))]

for i in mp:
    i.start()
    i.join()
print len(files)
Run Code Online (Sandbox Code Playgroud)

当我检查进程树时,我只能看到生成的一个智能进程.(man pstree说{}表示父母产生的子进程.)

---bash(10949)---python(12729)-+-python(12730)---{python}(12752)
                               `-python(12750)`
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是,为每个tld目录生成一个进程,填充共享列表files,这将是大约10-15个进程,具体取决于目录的数量.我究竟做错了什么?

编辑::

我曾经multiprocessing.Pool创建工作线程,这次生成了进程,但是在我尝试使用时会出错multiprocessing.Pool.map().我指的是显示的python文档中的以下代码

from multiprocessing import Pool
def f(x):
return x*x

if …
Run Code Online (Sandbox Code Playgroud)

python parallel-processing concurrency multiprocessing python-multiprocessing

6
推荐指数
1
解决办法
5037
查看次数

如果goroutines涉及用户空间线程,阻塞操作是否可以导致整个线程的上下文切换?

如果这个问题太愚蠢,请道歉.我是通过够程的细节阅读这里.根据那个页面,它说Goroutines are multiplexed onto a small number of OS threads, rather than a 1:1 mapping,我所能想到的只有我有限的知识是,产生的OS线程数量有限,其中可能使用用户空间线程或协同程序.它是否正确?如果是这样,如果我可以举一个例子,如果一个程序克隆4个OS线程,其中有多个用户空间线程,并且在所有这4个线程中发生了单个阻塞操作以及非阻塞操作,那么操作系统scheduler context-switch所有这些线程,因为用户空间线程对OS线程不透明?

出于好奇,是否有可能实现goroutines的C实现,这有助于理解内部结构?

multithreading pthreads go coroutine goroutine

6
推荐指数
1
解决办法
404
查看次数

使用指针在go中按预期工作,编辑结构列表变量

我有一个看起来像的结构

type Request struct {
    Name string `json:"name"`
    Parameters []Parameter `json:"parameters"`
}
Run Code Online (Sandbox Code Playgroud)

type Parameter struct {
    Attached bool `json:"attached"`
    Script string `json:"script"`
}
Run Code Online (Sandbox Code Playgroud)

现在,我已经将json解组到struct中,而Script变量的http位置为" http://localhost/helloworld.sh ".我想要做的是,Parameter.Scripthttp://localhost/helloworld.sh脚本的实际内容更改struct变量,这是一个简单的ascii shell脚本.我为内部结构编写了一个方法

func (p *Parameter) SetScript(script string)  {
    p.Script = script
}
Run Code Online (Sandbox Code Playgroud)

使用指针Parameter,

GetScript函数中,尝试在获取响应主体后调用该方法.

func GetScript(params *Request)  {
  for _, i := range params.Parameters {
    switch i.Attached {
    case false:
        client := new(http.Client)
        req, _ := http.NewRequest("GET", i.Script, nil)
        resp, _ := client.Do(req)
        defer resp.Body.Close()
        reader, …
Run Code Online (Sandbox Code Playgroud)

methods json struct pointers go

5
推荐指数
1
解决办法
83
查看次数

变量超出循环、条件或案例的范围后会发生什么?

提出这个问题的原因只是我的好奇心,想确定编写高性能流消费者从多个通道读取大尺寸字节数组的最佳实践是什么。(虽然过早的优化是万恶之源,但这更多的是出于好奇)。我已经阅读了有关特定于C 此处的类似方案的答案,但我要求特定的答案,因为它是一种垃圾收集语言,并且他们的文档在这里说“从正确性的角度来看,您不需要知道变量在哪里分配”。

如果我有以下代码可以从频道读取,

    for {
    select {
    case msg := <-stream.Messages():
    ...snip...
Run Code Online (Sandbox Code Playgroud)

变量msg在 case 语句的范围内。

  • 一旦超出case声明范围会发生什么?由于这是在同一个本机函数中声明的,并且 的大小stream可能是一个大字节片,因此该变量将存储在堆还是堆栈中,如果是堆,是否会被垃圾收集,或者堆栈指针是否出现?
  • 由于这是在无限 for 循环内,并且 的大小stream是一个大字节切片,因此每次都会创建变量并分配内存,或者我应该提前声明变量,并在每次迭代中继续覆盖它,因此,如果涉及垃圾收集(我不确定),我可能会减少垃圾吗?
  • 我根本不应该为此烦恼吗?

garbage-collection memory-management heap-memory go stack-memory

5
推荐指数
1
解决办法
1215
查看次数

将数据传递给嵌套模板未按预期工作

我试图让传递到围棋嵌套模板结构,使用html/template和尝试了使用既达到template.ParseFilestemplate.ParseGlob,而是因为我的理解是不明确它不工作按我的预期。

我的文件模板代码header.html

{{define "header"}}
<!DOCTYPE html>
<html lang="en">
<head>
    <link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> SiteAdmin - {{.User}}</title>
</head>
{{end}} 
Run Code Online (Sandbox Code Playgroud)

对于文件admin.html

{{template "header"}}
<body>
"User is {{.User}}"
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我在Execute*Template 类型上使用该方法作为

type Admin struct {
    User string
}


data := new(Admin)
data.User = "Guest"
tpl, err := template.ParseGlob("views/templates/admin/*.html")
CheckForErr(err)
err = tpl.Execute(w, data)
CheckForErr(err)
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,我可以将结构体数据传递给admin.html,并显示User is Guest在浏览器中。但是,如果我尝试将其传递给任何嵌套模板,则不会。页面标题仍然显示为SiteAdmin -SiteAdmin …

parsing nested http go go-templates

5
推荐指数
1
解决办法
1877
查看次数