还是Go 为了伟大的未来
今天,还是想讲讲Go
我觉得还没讲够,哈哈哈
其实,是想把框架再清晰些,因为上一篇框架没能引入goroutine(协程),感觉比较遗憾
下边,我就用上goroutine,但这里的协程仅是为了演示,没有任何提升处理效率的能力,切记
我主要是为了下篇博文做引子而已,哪里是讲web服务器的效率问题
记住,我之前的博文,都是为了把客户端的功能服务化,换句话说,没有效率不效率,并发连接数高低之说,如果一件事要一天做完,不好意思,你也必须等一天!就这么回事。人们常说的百万级,数亿级web服务,跟我说的就不是一回事
//package main
package main
import (
"Enroll_lib"
)
func server(pw32 *Enroll_lib.Win32_handle, X []string) string {
if 1<=len(X) {
if X[0]=="getVersion" {
version := pw32.GetVersion()
var ret string = ""
ret += "{"
ret += "\"result\""
ret += ":"
ret += "\""
ret += version
ret += "\""
ret += "}"
return ret
}
}
return ""
}
package main
import (
"fmt"
"os"
"net/http"
"Enroll_lib"
"strconv"
//"encoding/json"
)
func routine(c chan string, X []string) {
var w32_handle Enroll_lib.Win32_handle
var pw32 *Enroll_lib.Win32_handle = &w32_handle
res := pw32.LoadLib()
if !res {
fmt.Println("Load library failure")
}
res = pw32.GetHandle()
if !res {
fmt.Println("GetHandle failure")
}
var ret string
ret = server(pw32, X)
pw32.ReleaseHandle()
pw32.FreeLib()
c <- ret
}
func entry(res http.ResponseWriter, req *http.Request) {
req.ParseForm()
//fmt.Println("post KV count: ", len(req.PostForm))
count := len(req.PostForm)
if 1<=count {
var arr []string
method := req.PostFormValue("method")
arr = append(arr, method)
for i:=1; i<count; i++ {
arr = append(arr, req.PostFormValue("param"+strconv.Itoa(i)))
}
var c chan string
c = make(chan string)
go routine(c, arr)
ret := <- c
fmt.Fprintf(res, ret)
} else {
fmt.Fprintf(res, "RESTful web API has nothing to do, invalid request\n")
}
}
func main() {
Port := "8086"
IsHttp := true
arg_num := len(os.Args)
if 2<=arg_num {
Port = os.Args[1]
}
if 3<=arg_num {
if os.Args[2]=="true" {
IsHttp = true
} else {
IsHttp = false
}
}
fmt.Printf("server is http %t\n", IsHttp)
fmt.Println("server listens at ", Port)
http.HandleFunc("/", entry)
var err error
if IsHttp {
err = http.ListenAndServe(":"+Port, nil)
} else {
err = http.ListenAndServeTLS(":"+Port, "server.crt", "server.key", nil)
}
if err != nil {
fmt.Println("Server failure /// ", err)
}
fmt.Println("quit")
}
//package Enroll_lib
package Enroll_lib
import(
"fmt"
"syscall"
"C"
"unsafe"
)
type Win32_handle struct {
handle syscall.Handle
c_enroll_handle uintptr
c_lib_handle uintptr
err error
}
func (h *Win32_handle) LoadLib() bool {
h.handle, h.err = syscall.LoadLibrary("Enroll.dll")
if h.err!=nil {
fmt.Println("Enroll.dll not found")
return false
}
return true
}
func (h *Win32_handle) FreeLib() {
syscall.FreeLibrary(h.handle)
}
func (h *Win32_handle) GetHandle() bool{
getHandle, err := syscall.GetProcAddress(h.handle, "getHandle")
if err!=nil {
fmt.Println("getHandle not found")
return false
}
r,_,retstr := syscall.Syscall(uintptr(getHandle), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
0)
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failuer at getHandle")
return false
}
return true
}
func (h *Win32_handle) ReleaseHandle() {
releaseHandle, err := syscall.GetProcAddress(h.handle, "releaseHandle")
if err!=nil {
fmt.Println("releaseHandle not found")
}
r,_,retstr := syscall.Syscall(uintptr(releaseHandle), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
0)
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failuer at releaseHandle")
}
}
func (h *Win32_handle) FreeMem(p *C.char) {
freeMem, err := syscall.GetProcAddress(h.handle, "freeMem")
if err!=nil {
fmt.Println("freeMem not found")
}
r,_,retstr := syscall.Syscall(uintptr(freeMem), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
uintptr(unsafe.Pointer(&p)))
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failuer at freeMem")
}
}
func (h *Win32_handle) GetVersion() string {
getVersion, err := syscall.GetProcAddress(h.handle, "getVersion")
if err!=nil {
fmt.Println("getVersionm not found")
}
var p *C.char
r,_,retstr := syscall.Syscall(uintptr(getVersion), 3, uintptr(unsafe.Pointer(&h.c_enroll_handle)),
uintptr(unsafe.Pointer(&h.c_lib_handle)),
uintptr(unsafe.Pointer(&p)))
if false {
fmt.Println(retstr)
}
if r==0 {
fmt.Println("syscall failure at getVersion")
}
defer h.FreeMem(p)
return C.GoString(p)
}
Finally:
我只想提醒两点:
1. 不要试图把res http.ResponseWriter, req *http.Request传给协程去接着干,http不能跨协程
你希望的如此简易高并发,还是在此歇菜了吧,哈哈哈
2.web服务的HTTP请求-应答本身就不能并发,请求干的具体事务是可以并发执行的,这一点是web的本质,跟你用何种语言无关
天下难点是一致的,任何语言都是相通一致的
还是Go 为了伟大的未来的更多相关文章
- CSS的未来
仅供参考 前言 完成<CSS核心技术与实战>这本书,已有一个多月了,而这篇文章原本是打算写在那本书里面的,但本章讲解的内容,毕竟属于CSS未来的范畴,而这一切都还不能够确定下来,所以这一章 ...
- 从中间件的历史来看移动App开发的未来
在移动开发领域我们发现一个很奇怪的现象:普通菜鸟新手经过3个月的培训就可以拿到 8K 甚至上万的工作:在北京稍微有点工作经验的 iOS 开发,就要求 2 万一个月的工资.不知道大家是否想过:移动应用开 ...
- 展望未来:使用 PostCSS 和 cssnext 书写 CSS
原文链接:A look into writing future CSS with PostCSS and cssnext 译者:nzbin 像twitter,google,bbc使用的一样,我打算看一 ...
- 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)
坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...
- 如何理解DT将是未来IT的转型之路?
如今的IT面临着内忧外患的挑战. 一方面,企业多多少少都建立了信息化,有些企业或集团甚至会有数几十个分公司,包含直销.代理.零售以及第三方物流等多种业态.越是复杂的业务,信息化建设越困难,比如运用大量 ...
- 面向未来的友好设计:Future Friendly
一年前翻译了本文的一部分,最近终于翻译完成.虽然此设计思想的提出已经好几年了,但是还是觉得应该在国内推广一下,让大家知道“内容策略”,“移动优先”,“响应式设计”,“原子设计”等设计思想和技术的根源. ...
- 【流量劫持】SSLStrip 的未来 —— HTTPS 前端劫持
前言 在之前介绍的流量劫持文章里,曾提到一种『HTTPS 向下降级』的方案 -- 将页面中的 HTTPS 超链接全都替换成 HTTP 版本,让用户始终以明文的形式进行通信. 看到这,也许大家都会想到一 ...
- HTPC家庭娱乐和XBOX未来发展畅想<另:创业工作机会>
微软中国在上海举办新闻发布会,正式宣布Xbox One将于9月23日在中国开始销售,定价3699元起.这款早在2001年就发布的电视游戏机终于在经历了14年的等待后,进军中国大陆市场.此次Xbox O ...
- 2015游戏蛮牛——蛮牛杯第四届开发者大赛 创见VR未来开启报名
蛮牛杯启动了,大家开始报名! http://cup.manew.com/ 这不是一篇普通的通稿,别着急忽略它.它是一篇可以让你梦想变现的通稿! 从某一天开始,游戏蛮牛就立志要为开发者服务,我们深知这一 ...
- 来,一起让我们越来越懒,面向CSS、JS未来编程。(9.28已更新)
2016.10.29更新 本文存在大量的错误,仅供参考. 不知不觉在前端领域马上一个年头就要过去了,然而再看看自己的代码,果然够烂,那么为什么代码一直没有用面向对象的思维去写CSS呢?首先有两点:一点 ...
随机推荐
- 泡泡一分钟:Exploiting Points and Lines in Regression Forests for RGB-D Camera Relocalization
Exploiting Points and Lines in Regression Forests for RGB-D Camera Relocalization 利用回归森林中的点和线进行RGB-D ...
- 【魔改】树状数组 牛客多校第五场I vcd 几何+阅读理解
https://www.nowcoder.com/acm/contest/143/I vc-dimension 题解:分三种情况,组合数学算一下,其中一种要用树状数组维护 技巧(来自UESTC):1. ...
- win server 2008添加磁盘-脱机转换为联机状态方法
解决方案如下: 1.运行:cmd2.输入:DISKPART3.DISKPART> san4.DISKPART> san policy=onlineall5.DISKPART>list ...
- 用PIP 安装或升级python遇到错误提示
用PIP 安装或升级python遇到错误提示 $ pip install pythons Collecting pythons Could not find a version that satisf ...
- RabbitMQ 内存控制 硬盘控制
RabbitMQ服务器在启动时以及abbitmqctl set_vm_memory_high_watermark fraction 执行时,会检查计算机的RAM总大小. 默认情况下下, 当 Rabbi ...
- .net WebService的使用
1. WebService可单独作为一个网站,不限平台的被调用. 2. 打开VS,选择新建 3. [WebMethod] 方法上面有这个说明,则表示此方法可被外部调用. 我们添加4个方法:加.减.乘. ...
- mysql查询表死锁和结束死锁的方法
1.查询是否锁表 show open tables where in_use>0; 2.查询进程 show processlist 查询到相对应的进程,然后 kill id 3.查看正在锁的事务 ...
- day3_字符串常用方法
s.upper()s.lower()s.capitalize()s.split(',')s.strip('abc')s.lstrip()s.rstrip()s.replace('old','new') ...
- LeetCode 784 Letter Case Permutation 解题报告
题目要求 Given a string S, we can transform every letter individually to be lowercase or uppercase to cr ...
- word标题自动编号
1.打开word文档中多级列表->定义新的多级列表 2.根据下图设置级别对应的标题,然后确定