GO多线程处理结算

第一次尝试使用GO语言开启多线程调用结算存储过程。记录一下,以防忘记~

package main

import (

    "database/sql"

    "fmt"

    "runtime"

    "strconv"

    _ "github.com/go-sql-driver/mysql"

)

// 创建一个channel

var complete chan int = make(chan int, 1)

var doState int = 0

func main() {
    var errMsg string

    var processNum, distribState int = 1, 0

    fmt.Println("start")

    db, err := sql.Open("mysql", "root:@127.0.0.1/test?charset=utf8")

    if err != nil {

        errMsg = "sql.Open:" + err.Error()

    } else {

        row := db.QueryRow("select ifnull(processNum,0),ifnull(distribState,0) from tb_calpara limit 1")

        err := row.Scan(&processNum, &distribState)

        if err != nil {

            if err == sql.ErrNoRows {

                errMsg = "未设置系统参数!"

            } else {

                errMsg = "row.Scan:" + err.Error()
            }

        } else {

            //未开始分配

            if distribState == 0 {

                runtime.GOMAXPROCS(processNum)

                var minQuotaID, maxQuotaID, beforeMax int

                ssql := ` select min(quotaID) , max(quotaID) from tb_quota
                    where dataState in (2,3)
                                and ((lastPassDate is null and DATE_FORMAT(quotaDate,'%Y-%m-%d')<DATE_FORMAT(NOW(),'%Y-%m-%d'))
                                  or (lastPassDate is not null and DATE_FORMAT(lastPassDate,'%Y-%m-%d')<DATE_FORMAT(NOW(),'%Y-%m-%d')))`

                row := db.QueryRow(ssql)

                err := row.Scan(&minQuotaID, &maxQuotaID)

                if err != nil {

                    fmt.Println("111", err.Error())

                } else {

                    if minQuotaID > 0 && maxQuotaID > 0 && processNum > 0 {

                        //求一个平均数

                        avg := (maxQuotaID - minQuotaID) / processNum

                        for i := 1; i <= processNum; i++ {

                            var min, max int

                            if i == 1 { //第一个

                                min = minQuotaID

                                max = min + avg

                            } else if i == processNum { //最后一个

                                min = beforeMax

                                max = maxQuotaID + 1

                            } else { //中间

                                min = beforeMax

                                max = min + avg

                            }

                            go autoDistrib(db, min, max, complete)

                            beforeMax = max

                        }

                    }

                }

            }

        }

    }

    var value string

    for j := 1; j <= processNum; j++ {

        v := <-complete // 直到线程跑完, 取到消息. main在此阻塞住

        value = value + strconv.Itoa(v) + ","

        fmt.Println("channel:", value)

    }

    fmt.Println("channel的值为:", value)

    var dstate int

    row := db.QueryRow(`select ifnull(distribState,0) from tb_calpara limit 1`)

    row.Scan(&dstate)

    if dstate == processNum {         

       //修改参数表的分配状态

       _, err := db.Exec(`update tb_calpara set distribState=ifnull(distribState,0)+1 limit 1;`)

        if err != nil {

            fmt.Println("444", err.Error())

        }            
 
    }

    fmt.Println("main函数运行结束...", errMsg)

    defer db.Close()

}

//分配

func autoDistrib(db *sql.DB, min int, max int, ch chan int) {

    fmt.Println("新线程运行开始...", min, max)

    var isOk int = -1

    var err string

    //调用autoDistrib存储过程

    _, xerr := db.Exec(`call proc_autoDistrib( 
                            ?,  -- min ID
                            ?,  -- max ID 
                            @isOK,
                            @err
                            );`, min, max)

    if xerr != nil {
        fmt.Println("distrib error: ", xerr)

    } else {

        row := db.QueryRow("select ifnull(@isOK,0), ifnull(@err,'');")

        row.Scan(&isOk, &err)

        if isOk < 0 {
            fmt.Println("err:" + err)
        }
    }

    doState = doState + 1

    ch <- doState

    fmt.Println(doState, min, max)

    fmt.Println("新线程运行结束...")

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值