正如我们在go中所知,当goroutine必须执行阻塞调用(例如系统调用)或通过cgo调用C库时,可能会创建一个线程.一些测试代码:
package main
import (
"io/ioutil"
"os"
"runtime"
"strconv"
)
func main() {
runtime.GOMAXPROCS(2)
data, err := ioutil.ReadFile("./55555.log")
if err != nil {
println(err)
return
}
for i := 0; i < 200; i++ {
go func(n int) {
for {
err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm)
if err != nil {
println(err)
break
}
}
}(i)
}
select {}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它没有创建很多线程.
? =99=[root /root]$ cat /proc/9616/status | grep -i thread
Threads: 5
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
class CSample{
int a;
// ..... lots of fields
}
Csample c;
Run Code Online (Sandbox Code Playgroud)
我们知道,Csample有一个默认的复制构造函数.当我这样做:
Csample d = c
Run Code Online (Sandbox Code Playgroud)
将发生默认的复制构造函数.我的问题是:它是线程安全的吗?因为c在执行复制构造函数时,可能有人在另一个线程中进行了修改.如果是这样,编译器如何做到这一点?如果没有,我认为编译器无法保证复制构造函数是线程安全的,这太可怕了.
type MyMap struct {
data map[int]int
}
func (m Mymap)foo(){
//insert or read from m.data
}
...
go func f (m *Mymap){
for {
//insert into m.data
}
}()
...
Var m Mymap
m.foo()
Run Code Online (Sandbox Code Playgroud)
当我调用m.foo()时,正如我们所知,有一个"m",值复制的副本,由编译器完成.我的问题是,程序中是否有竞争?它是来自var"m"的某种读取数据,我的意思是,如果有人在从m.data复制内容时将值插入m.data,则可能需要读取锁定.
如果它是线程安全的,它是否由编译器保护?
我从"更有效的C++"第18项中读到了一些内容:
简而言之,迭代器是一个对象,而不是一个指针,因此无法保证" - >"可以应用于它.†STL确实要求"."和"*"对迭代器有效,但是,所以(*它).第二,尽管语法上很笨拙,但保证可以工作.)
通常,我->在迭代器上使用并没有任何问题.任何人都可以举例或解释吗?
给定"notify","publicKey"和"sign",它没有通过VerifyPKCS1v15in go.那是我的代码,有什么不对吗?
package main
import (
"crypto"
"crypto/sha1"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
)
func main() {
notify := `YFSGlJTpNYakrZuZqZ55dcA5mVUb/JQBr3hdDjODsAVSdoVVytIagk9Wt0CD/uX+7jGL9pqev8/u0I0ZBKEmz5huXp8TdZSnskCZ7GTeHNW0VPJcW8OcBxAValA0jQSv2mBP+tc1r6mdvf66GEzhvgBfTnp3Sp7V3dijJ9bNstIDyrGm/BlByhcMr3UqXjTFJaui6t5TxvZhCuSV9sg+xVVA+sR3uFI78b5lKomg5Vu31EBZvXASlFfaOc4StltRUH2aSiRqjnbXe8dlRZO0Ih44htYs2QfehzeQnPHtTwNHUvtVIVcIdI/7j9yfy5es13QeIgfKghY/ENUnB2V7iA==`
sign := `s8XIN2TyC5niX1HFPDXOQj2eRvhW2qMPOdDuuXlOspYhxkjxunV4Ytgcw8GXg761HSbk4e5QsgKpU+vM2ggLhYni2GfXhGBVj/P13B6JhMmdrucU8ktlaH+fJGUmc3rqGMU3qiQgNAh/8PV1BS/5li7qzXHc0tgKL1zRgeu1CVw=`
notifyData, err := base64.StdEncoding.DecodeString(notify)
if err != nil {
fmt.Println("error1:", err)
return
}
signData, err := base64.StdEncoding.DecodeString(sign)
if err != nil {
fmt.Println("error2:", err)
return
}
publicKey := []byte(`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2kcrRvxURhFijDoPpqZ/IgPlA
gppkKrek6wSrua1zBiGTwHI2f+YCa5vC1JEiIi9uw4srS0OSCB6kY3bP2DGJagBo
Egj/rYAGjtYJxJrEiTxVs5/GfPuQBYmU0XAtPXFzciZy446VPJLHMPnmTALmIOR5
Dddd1Zklod9IQBMjjwIDAQAB
-----END PUBLIC KEY-----
`)
block, _ := pem.Decode(publicKey)
if block == nil {
fmt.Println("pem error :")
return
}
public, err …Run Code Online (Sandbox Code Playgroud) 我有一台服务器并启动goroutine来发送数据.像这样的代码
func handleSend(conn *net.TcpConn, ch <-chan []byte) {
for {
select {
case msg, ok := <-ch:
if !ok {
return
}
n, err := conn.Write(msg)
if err != nil {
log.Error("conn write error", err)
return
}
//here
}
}
}
Run Code Online (Sandbox Code Playgroud)
今天,我想我应该检查n返回,conn.Write以确保msg完全写入.所以我在这个地方添加了以下代码here
for ;n!= len(msg);{
log.Error("conn write not completely", len(msg), "actually", n)
msg = msg[n:]
n, err = sess.conn.Write(msg)
if err != nil {
log.Error("conn write error", err)
return
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道这样做是对的吗?PS如果对等体缓慢接收消息并Write …
我的服务器运行了一段时间,创建了大约200个连接并进行了一些计算并关闭,我发现它占用了大约2,7G的内存并且在几天之后从未减少.程序本身并没有占用那么多,我查了一下memstats.通过cat /proc/11686/status | grep -i threads 我Threads: 177,所以我认为它拿起之所以这么多的内存是它创建多个线程.为什么go创造那么多线程?是因为我用的太多了go func()吗?我确信goroutines没有增加,他们正常退出.
PS
我的程序中有很多代码,所以我排除了细节,只保留主要内容
我的问题是go创建一个线程来做某事.拥有这么多线程是正常的吗?我认为它对代码并不重视.
main.go
package main
import (
"sanguo/base/log"
"fmt"
"runtime"
"math/rand"
"time"
"net"
"os"
)
type GameServer struct {
Host string
}
func (server *GameServer) Start() {
// load system data
log.Debug("/*************************SREVER START********************************/")
tcpAddr, err := net.ResolveTCPAddr("tcp4", server.Host)
if err != nil {
log.Error(err.Error())
os.Exit(-1)
}
go func(){
for{
select {
case <-time.After(30*time.Second):
LookUp("read memstats")
}
}
}()
listener, …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <string>
#include <deque>
#include <vector>
#include <unistd.h>
using namespace std;
struct Node
{
string str;
vector<string> vec;
Node(){};
~Node(){};
};
int main ()
{
deque<Node> deq;
for(int i = 0; i < 100; ++i)
{
Node tmp;
tmp.vec.resize(100000);
deq.push_back(tmp);
}
while(!deq.empty())
{
deq.pop_front();
}
{
deque<Node>().swap(deq);
}
cout<<"releas\n";
sleep(80000000);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
通过top,我发现我的程序的内存大约是61M,为什么?如果有一个复制构造函数就可以了Node.我想知道原因,而不是如何使它正确.
gcc(GCC)4.9.1,centos