This is a creation in Article, where the information may have evolved or changed.
Take the time to see what Google's go language is all about. Go said is good, since C-dependent, n years did not have a classic programming language, computer development for decades, language or C of that set, is to make a difference, do it really not easy ah. See where go is doing well.
Compile Package
Python is good, just depends on the python environment, such as CentOS5.5 is Python2.5, there is no JSON ...
If the. Py developed on the CentOS6, put it directly to the CentOS5.5, it may not be able to run, and this is still a headache for commercial deployment.
One way is to compile the Python2.6 virtual machine, and you can use Cxfreeze and Pyinstaller as a binary, no longer dependent on the Python environment.
Generally is the choice of the latter one, generally compiled files a few trillion or so, and the program compiled with C/s is no different.
Well, let's see Go,go is not an explanatory language, but a static language. So it can be compiled:
Hello.gopackage mainimport "FMT" Func Main () { fmt. Printf ("Hello, world!\n")}
Compile:
[Winlin@dev6 go-rtmp]$ go Build hello.go [winlin@dev6 go-rtmp]$ ls-lh-rwxrwxr-x 1 winlin winlin 2.2M Jan 22:31 Hello
To view dependencies, rely only on libc:
[Winlin@dev6 bin]$ ldd gotour linux-vdso.so.1 = (0x00007fff263ff000) libpthread.so.0 =/lib64/ libpthread.so.0 (0x0000003856600000) libc.so.6 =/lib64/libc.so.6 (0x0000003855a00000)/lib64/ Ld-linux-x86-64.so.2 (0x0000003855200000)
About Gopath, in fact, is similar to Python's site-packages, such as:
Go get Code.google.com/p/go-tour/gotour
This command will download the Go-tour as well as the dependent packages in $gopath, and then compile the Gotour execution file, which can be executed directly $gopath/bin/gotour.
Go get is equivalent to executing the following command:
This command executes: mkdir-p $GOPATH/src && cd $GOPATH/src mkdir-p code.google.com/p && cd code.google.com /P HG clone https://code.google.com/p/go-tour then download dependent items: cd $GOPATH/src/code.google.com/p HG clone https ://code.google.com/p/go.tools HG clone https://code.google.com/p/go.net then starts compiling: mkdir-p $GOPATH/bin & & CD $GOPATH/bin go build code.google.com/p/go-tour/gotour actually the last step of go get is not build, but install: mkdir-p $ Gopath/bin && cd $GOPATH/bin go install code.google.com/p/go-tour/gotourinstall will generate pkg. Gopath is used to specify this dir, you can call go install in any directory, will generate to gopath this directory.
When you install a package on go, you are asked to have a rule for the directory structure of the Gopath to see go help.
In general, you can use two Gopath, one for which dependent packages, and one for your own package. Reference: Https://code.google.com/p/go-wiki/wiki/GOPATH#Repository_Integration_and_Creating_
For example, set the following in/etc/profile:
# for Google go. Export Goroot=/usr/local/go export gopath=/home/winlin/git/google-go:/home/winlin/git/go-rtmp export PATH = $PATH: $GOROOT/bin
Execution: Go get code.google.com/p/go-tour/gotour
The following items will be generated:
[Winlin@centos6x86 ~]$ ls/home/winlin/git/google-go/src/code.google.com/p/go.net go.tools go-tour
The external dependent library is installed in the directory where the first Gopath is located.
Build the package in your own directory, for example: Mkdir-p/home/winlin/git/go-rtmp/src/hello
Then: Vim/home/winlin/git/go-rtmp/src/hello/hello.go
Enter the following:
Package Mainimport "FMT" import "Math" Func Main () { fmt. Println (Math. Pi)}
You can compile the package in any location:
[Winlin@centos6x86 ~]$ Go build hello[winlin@centos6x86 ~]$ pwd/home/winlin[winlin@centos6x86 ~]$ ls-lh hello-rwxrwxr-x . 1 Winlin winlin 1.8M Jan 21:50 hello[winlin@centos6x86 ~]$./hello 3.141592653589793
In fact, if you compile an incorrect package, the directory location where go looks is displayed:
[Winlin@centos6x86 ~]$ Go build hellscan ' t load package:package hells:cannot Find package "hells" in any of:/usr/local/g O/src/pkg/hells (from $GOROOT)/home/winlin/git/google-go/src/hells (from $GOPATH)/home/winlin/git/go-rtmp/src/ Hells
Visible is to go to Goroot first find, and then go to all the Gopath find.
In short, go has no problem compiling the package.
Package dependencies
The core goal of GO is mass programming, so it must be tough to deal with dependencies. That is, the user does not need to deal with any compiled dependencies, go automatic processing, only need to comply with the language of the package specification.
This is still really good, to know that compiling a ffmpeg is really not easy, rely on large, version of the majority, compile errors may be found after the error of the library dependencies, and so on, is indeed a difficult thing.
How does go deal with this problem? See how to compile SRS, which is two versions of C + + and go, respectively.
Reference: http://dev:6060/doc/code.html
C + + version, reference: Https://github.com/winlinvip/simple-rtmp-server
git clone https://github.com/winlinvip/simple-rtmp-server cd simple-rtmp-server/trunk./configure--with-ssl-- With-hls--with-ffmpeg--with-httpmake
Is it actually okay? In fact, if the CentOS6 under the compilation, basically no problem, if a change of environment? The compilation failed for sure. The reason is configrure do a lot of things, need to install Gcc/g++/make and other tools, need to compile nginx/ffmpeg, compile nginx need to install Pcre, install ffmpeg need libaacplus/liblame/libx264 , and so on, is really not easy for a script.
Depending on the project, you have to use a wiki to get it done: Https://github.com/winlinvip/simple-rtmp-server/wiki/Build
Go version, reference: Https://github.com/winlinvip/go.srs
Export Gopath=~/mygogo Get Github.com/winlinvip/go.srs/go_srs
So you can do it? Yes, that's OK.
The SRS compilation for C + + is in:./objs/srs
SRS compilation on Go: $GOPATH/bin/go_srs
In fact go does a lot of things, because the other packages that Go.srs relies on are written according to go specifications, so the go get command can download the required dependencies automatically and compile them.
See Gopath to know what it does:
[Winlin@centos6x86 ~]$ tree $GOPATH/home/winlin/mygo├──bin│ └──go_srs├──pkg│ └──linux_386│ └── github.com│ └──winlinvip│ └──go.rtmp│ └──rtmp.a└──src └──github.com └──winlinvip ├── Go.rtmp │ ├──license │ ├──readme.md │ └──rtmp │ └──version.go └── Go.srs ├──go_srs │ └──srs.go ├──license ├──readme.md └──research └── Demo-func └──func_declare.go
In addition to Go.srs, even Go.srs-dependent go.rtmp is downloaded and compiled automatically.
Go get is equivalent to downloading and installing:
Go get-d github.com/winlinvip/go.srs/go_srsgo Install Github.com/winlinvip/go.srs/go_srs
The price is the package will be longer, the advantage is a command, to take care of all the things, this is great ~
Concurrency and Parallel Computing
Undoubtedly the design goal of Go is large-scale program, concurrency and parallel computing is very important and a big feature. With fashionable words, go is born of cloud computing. From a domain perspective, go is designed for writing servers/services.
No matter what word you use, the cloud/service has one important feature: The system provides services for multiple people at the same time, which is concurrency and parallel computing. Concurrency only supports multi-person capabilities at the same time, and parallel computing refers to computing systems that utilize multiple CPUs and multiple machines. Single process can also support concurrency, using Linux epoll and non-blocking asynchronous sockets can be done, nginx is typical. Only the server is basically multi-CPU, so support multi-process will also have a great advantage, Nginx is also typical.
Multi-process programming can be consulted: http://blog.csdn.net/win_lin/article/details/7755773
Asynchronous non-blocking can bring the highest performance, the trouble is that the state machine is very complex, so for the complex state machine, such as RTMP protocol, the State transformation of large, with the association (co-process/lightweight thread/user-state thread) and other technologies can be asynchronous based on the use of synchronization, reference to:/HTTP blog.csdn.net/win_lin/article/details/8242653
C + + does not provide language-level coprocessor support, but some libraries provide support (Python provides the yield keyword, but the support is not perfect, with Eventlet library support), and go is important to provide support at the language level.
The C/s library generally only provides support for the process, and the support for multiple processes is limited; go supports both co-and multi-process, and the go runtime itself is multithreaded.
Explained in detail in Effectivego: http://dev:6060/doc/effective_go.html#concurrency
The following two goroutine are opened, and the cumulative operation is continued:
Package Mainimport ("FMT" "Time") Func main () {var fun = func (id int) {count: = 0for {if (count% 1500000000) = = 0 {fmt. Printf ("[%v] Id=%v, count=%v\n", time. Now (). Format ("2006-1-06 15:04:05"), ID, count)}count++}}go Fun (101) Go Fun (102) time. Sleep (* time. Second)}
The calculation results are as follows:
C:/go/bin/go.exe run r:/mygo/go.srs/research/demo/tour/go_concurrency.go[2014-2-14 11:08:02] id=101, count=0[ 2014-2-14 11:08:02] id=102, count=0[2014-2-14 11:08:07] id=101, count=1500000000[2014-2-14 11:08:09] id=102, count= 1500000000[2014-2-14 11:08:11] id=101, count=3000000000[2014-2-14 11:08:14] id=102, count=3000000000[2014-2-14 11:08:16] id=101, count=4500000000[2014-2-14 11:08:19] id=102, count=4500000000[2014-2-14 11:08:21] id=101, count= 6000000000[2014-2-14 11:08:23] id=102, count=6000000000[2014-2-14 11:08:26] id=101, count=7500000000[2014-2-14 11:08:28] id=102, count=7500000000[2014-2-14 11:08:30] id=101, count=9000000000[2014-2-14 11:08:33] id=102, count= 9000000000[2014-2-14 11:08:35] id=101, count=10500000000
It can be seen that these two goroutine are executed alternately, and the go runtime dispatches them. View Cpu,4cpu 25% that's 1CPU.
With just one sentence, you can take advantage of multi-CPU multi-process parallel computing:
Runtime. Gomaxprocs (2)
Two CPUs will be calculated with the following code:
Package Mainimport ("FMT", "Time" "Runtime") func main () {var fun = func (id int) {count: = 0for {if (count% 1500000000) = = 0 {FMT. Printf ("[%v] Id=%v, count=%v\n", time. Now (). Format ("2006-1-06 15:04:05"), ID, count)}count++}}if runtime. NUMCPU () > 1 {runtime. Gomaxprocs (2)}go Fun (101) Go Fun (102) time. Sleep (* time. Second)}
The results of the operation are as follows:
C:/go/bin/go.exe run r:/mygo/go.srs/research/demo/tour/go_parallelization.go[2014-2-14 11:12:22] id=101, count=0[ 2014-2-14 11:12:22] id=102, count=0[2014-2-14 11:12:25] id=102, count=1500000000[2014-2-14 11:12:25] id=101, count= 1500000000[2014-2-14 11:12:28] id=102, count=3000000000[2014-2-14 11:12:28] id=101, count=3000000000[2014-2-14 11:12:31] id=102, count=4500000000[2014-2-14 11:12:31] id=101, count=4500000000[2014-2-14 11:12:34] id=102, count= 6000000000[2014-2-14 11:12:34] id=101, count=6000000000[2014-2-14 11:12:38] id=102, count=7500000000[2014-2-14 11:12:38] id=101, count=7500000000[2014-2-14 11:12:41] id=102, count=9000000000[2014-2-14 11:12:41] id=101, count= 9000000000[2014-2-14 11:12:44] id=102, count=10500000000[2014-2-14 11:12:44] id=101, count=10500000000
These two processes are parallel operations, and 4CP takes 50% or 2CPU at work.
What if I use C + +? Need to use libraries, such as state-threads, and then multi-process need fork, if need to communicate, also need to use interprocess communication technology, really very troublesome.
Where's go? A go keyword that supports both co-and multi-process communication with channel. Simple ~
Reflect reflex
Reflection is a meta-programming concept, referring to "the Laws of Reflection": http://dev:6060/blog/laws-of-reflection
Simply put, the basic type of reflect is type and value, that is, the types and values of variables.
Type.elem is the acquisition element type, such as type **myclass,type.elem is *myclass,type.elem (). Elem () is MyClass. In other words, it is similar to the role of the C + + *, take the value of the pointer.
Value.elem and Type.elem are the corresponding values that are manipulated.
Value.canset and Value.set are set on variables, just as in C + +, only pointers can be set.
Package Mainimport ("FMT" "reflect") type Blackwinlin struct {id int}type redwinlin struct {name String}func main () {bw: = B Lackwinlin{id:10}var rtmp_pkt *redwinlin = nilfmt. Println ("rtmp==========================") rtmp_pkt = Nilif My_rtmp_expect (&BW, &rtmp_pkt) {fmt. Println ("Discoveryed pkt from Black:", rtmp_pkt)}fmt. Println () rtmp_pkt = Nilif my_rtmp_expect (&redwinlin{}, &RTMP_PKT) {fmt. Println ("Discoveryed pkt from Red:", RTMP_PKT)}fmt. Println () fmt. Println ("rtmp==========================") var src_black_pkt *blackwinlin = &bwvar src_red_pkt *RedWinlin = & Redwinlin{name: "Hello"}rtmp_pkt = Nilif my_rtmp_expect (&src_black_pkt, &rtmp_pkt) {fmt. Println ("Discoveryed pkt from Black:", rtmp_pkt)}fmt. Println () rtmp_pkt = Nilif My_rtmp_expect (&src_red_pkt, &rtmp_pkt) {fmt. Println ("Discoveryed pkt from Red:", RTMP_PKT)}fmt. Println () fmt. Println ("rtmp==========================")//Set the value which is ptr to ptrvar prtmp_pkt **redwinlin = Nilif my_rtmp_exp ECT (&src_red_pkt, prtmp_pkt) {fmt. Println ("Discoveryed pkt from Red (PTR):", Prtmp_pkt) fmt. Println ("Discoveryed pkt from Red (value):", *prtmp_pkt)}prtmp_pkt = &rtmp_pktif My_rtmp_expect (&SRC_RED_PKT, PRTMP_PKT) {fmt. Println ("Discoveryed pkt from Red (PTR):", Prtmp_pkt) fmt. Println ("Discoveryed pkt from Red (value):", *prtmp_pkt)}}func my_rtmp_expect (PKT interface {}, V interface {}) (ok bool) {/ * Func my_rtmp_expect (PKT interface {}, V interface {}) {RT: = reflect. TypeOf (v) rv: = reflect. ValueOf (v)//Check the convertible and convert to the value or PTR value. For example, the V-like the C + + code:msg**v Pkt_rt: = reflect. TypeOf (PKT) if Pkt_rt. Convertibleto (RT) {//Directly match, the PKT is like C + +: MSG**PKT//Set the V by: *v = *pkt Rv. Elem (). Set (reflect. ValueOf (PKT). Elem ()) return} if Pkt_rt. Convertibleto (Rt. Elem ()) {//PTR match, the PKT is like c++: MSG*PKT//Set the V by: *v = PKT RV. Elem (). Set (reflect. ValueOf (PKT)) return}} */ok = Falsepkt_rt: = reflect. TypeOf (PKT) PKT_RV: = reflect. ValueOf (PKT) Pkt_ptr_rt: = reflect. Ptrto (pkt_rt) RT: = Reflect. TypeOf (v) rv: = reflect. ValueOf (v) if RV. Kind ()! = reflect. Ptr | | Rv. Isnil () {fmt. PRINTLN ("Expect must is PTR and not nil") return}fmt. PRINTLN ("type info, src:", Pkt_rt, "PTR (SRC):", Pkt_ptr_rt, ", Expect:", RT) FMT. PRINTLN ("Value info, src:", pkt_rv, ", Src.) Elem (): ", Pkt_rv. Elem (), ", Expect:", RV, ", expect. Elem (): ", RV. Elem ()) fmt. Println ("Convertible src=>expect:", Pkt_rt. Convertibleto (RT)) FMT. Println ("PTR convertible ptr (src) =>expect:", Pkt_ptr_rt. Convertibleto (RT)) FMT. Println ("Elem convertible src=>expect. Elem () ", Pkt_rt. Convertibleto (Rt. Elem ())) Fmt. Println ("settable src:", pkt_rv. Canset (), ", Expect:", RV. Canset ()) fmt. Println ("Elem settable src:", pkt_rv. Elem (). Canset (), ", Expect:", RV. Elem (). Canset ())//Check the convertible and COnvert to the value or PTR value.//for example, the V like the C + + code:msg**vif RV. Elem (). Canset () {if pkt_rt. Convertibleto (RT) {//Directly match, the PKT is like C + +: msg**pkt//Set the V by: *v = *pktfmt. Println ("Directly match, Src=>expect") rv. Elem (). Set (PKT_RV. Elem ()) ok = Truereturn}if Pkt_rt. Convertibleto (Rt. Elem ()) {//PTR match, the PKT is like C + +: msg*pkt//Set the V by: *v = pktfmt. PRINTLN ("Pointer match, Src=>*expect") rv. Elem (). Set (PKT_RV) ok = truereturn}fmt. Println ("Not match, Donot set expect")} else {fmt. PRINTLN ("Expect cannot set")}return}
The Go language problem
Go Language rtmp server: Https://github.com/winlinvip/go.srs
C + + language rtmp server: Https://github.com/winlinvip/simple-rtmp-server
Go has only C + + performance of 1/30, in 50 connections, go occupies cpu50%,c++ only 2%. Of course, there should be a problem with code writing. At least there is no way to go.