如何在两个不同终端运行Golang文件
如何在两个不同终端运行Golang文件 我实现了一个简单的钱包间交易功能,想要从第一个终端执行交易(从A向B转账),同时从第二个终端检查B钱包的余额。但问题是当我同时运行两个终端时,第二个终端会一直等待第一个终端执行完成。
3 回复
能分享一下你的解决方案吗?是让每个终端作为独立的goroutine运行,还是采用了其他方法?
在Golang中实现跨终端通信需要采用进程间通信(IPC)机制。以下是几种解决方案:
1. 使用文件锁(File Locking)
// 余额检查端
package main
import (
"fmt"
"os"
"syscall"
"time"
)
func checkBalance() {
file, err := os.OpenFile("balance.lock", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
panic(err)
}
defer file.Close()
// 非阻塞文件锁
err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
if err != nil {
fmt.Println("等待交易完成...")
// 等待锁释放
syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
}
// 读取余额
balance := readBalance()
fmt.Printf("B钱包余额: %d\n", balance)
syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
}
func readBalance() int {
// 实现读取余额逻辑
return 100
}
2. 使用网络Socket通信
// 交易执行端
package main
import (
"fmt"
"net"
"time"
)
func executeTransaction() {
// 先通知余额检查端
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
fmt.Println("余额检查端未启动")
return
}
defer conn.Close()
// 发送交易开始信号
conn.Write([]byte("TRANSACTION_START"))
// 执行交易逻辑
fmt.Println("执行A向B转账...")
time.Sleep(2 * time.Second)
// 发送交易完成信号
conn.Write([]byte("TRANSACTION_END"))
}
// 余额检查端
func balanceChecker() {
ln, err := net.Listen("tcp", ":8080")
if err != nil {
panic(err)
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
buffer := make([]byte, 1024)
n, err := conn.Read(buffer)
if err != nil {
return
}
message := string(buffer[:n])
if message == "TRANSACTION_START" {
fmt.Println("检测到交易开始,等待完成...")
// 等待交易完成
n, err = conn.Read(buffer)
if err == nil && string(buffer[:n]) == "TRANSACTION_END" {
fmt.Println("交易完成,当前余额:", getCurrentBalance())
}
}
}
func getCurrentBalance() int {
return 150
}
3. 使用共享内存+信号量
// 共享状态管理
package main
import (
"fmt"
"sync"
"time"
)
var (
transactionInProgress bool
mutex sync.RWMutex
)
// 交易执行端
func performTransaction() {
mutex.Lock()
transactionInProgress = true
mutex.Unlock()
defer func() {
mutex.Lock()
transactionInProgress = false
mutex.Unlock()
}()
fmt.Println("执行转账交易...")
time.Sleep(3 * time.Second)
fmt.Println("交易完成")
}
// 余额检查端
func checkBalanceWithWait() {
for {
mutex.RLock()
inProgress := transactionInProgress
mutex.RUnlock()
if !inProgress {
break
}
fmt.Println("交易进行中,等待...")
time.Sleep(500 * time.Millisecond)
}
fmt.Printf("B钱包余额: %d\n", readWalletBalance())
}
func readWalletBalance() int {
return 200
}
4. 使用Channel通信(推荐)
// 主服务端
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
var (
balance = 1000
balanceLock sync.RWMutex
transactionChan = make(chan bool, 1)
)
func main() {
http.HandleFunc("/transfer", handleTransfer)
http.HandleFunc("/balance", handleBalanceCheck)
go processTransactions()
http.ListenAndServe(":9090", nil)
}
func handleTransfer(w http.ResponseWriter, r *http.Request) {
transactionChan <- true
fmt.Fprintf(w, "交易请求已接收")
}
func handleBalanceCheck(w http.ResponseWriter, r *http.Request) {
balanceLock.RLock()
defer balanceLock.RUnlock()
fmt.Fprintf(w, "当前余额: %d", balance)
}
func processTransactions() {
for range transactionChan {
balanceLock.Lock()
fmt.Println("开始交易处理...")
time.Sleep(2 * time.Second)
balance += 100 // 模拟余额更新
fmt.Println("交易处理完成")
balanceLock.Unlock()
}
}
使用示例:
# 终端1: 启动服务
go run main.go
# 终端2: 检查余额
curl http://localhost:9090/balance
# 终端3: 执行交易
curl http://localhost:9090/transfer
推荐使用第4种HTTP服务的方式,它提供了最好的跨终端兼容性和可扩展性。

