一、Go语言的并行执行
Go语言的一个显著优势在于其简洁的并行执行机制,通过goroutine可以轻松实现并发任务。以下代码示例展示了如何定义run_cmd函数,利用os/exec包执行外部命令字符串,并通过sync.WaitGroup管理并发流程:每个任务启动时计数器加一,完成时减一,主函数使用wg.Wait()等待所有任务结束后退出。
package main
import (
"os"
"os/exec"
"sync"
"fmt"
)
var wg sync.WaitGroup
func run_cmd(cmd_string string, id int) {
defer wg.Done()
fmt.Printf("cmd(%d) start...\n", id)
cmd := exec.Command("sh", "-c", cmd_string)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start()
cmd.Wait()
fmt.Printf("cmd(%d) done\n", id)
}
func main() {
// 启动第一个命令
wg.Add(1)
go run_cmd(cmd_string, 1)
// 启动第二个命令
wg.Add(1)
go run_cmd(cmd_string, 2)
// 等待所有命令完成
wg.Wait()
fmt.Println("exit")
}
二、并行ICT转CAPTABLE
在实际的集成电路设计场景中,经常需要将多个ICT文件并行转换为CAPTABLE格式。假设有三个ICT文件:CMAX.ict、CMIN.ict和TYPICAL.ict,仅corner名称不同。通过Go的并发编程特性,可以高效处理这一任务。以下代码使用for range循环迭代corner数组,动态拼接命令字符串,并并行执行转换。
// ict2captable.go
// ... 省略import、wg和run_cmd定义
func main() {
corners := []string{"CMAX", "CMIN", "TYPICAL"}
for i, c := range corners {
wg.Add(1)
cmd_string := "generateCapTbl -lef ../../SCC018V3EBCD_TF_V0p7/innovus/scc018v3ebcd_1p3m_2ia_1mtt2.lef -ict QRC_018V3EBCD_1P3M_2Ia_1MTT2_1stMIM20_" + c + ".ict -output QRC_018V3EBCD_1P3M_2Ia_1MTT2_1stMIM20_" + c + ".captable"
go run_cmd(cmd_string, i)
}
wg.Wait()
fmt.Println("exit")
}
三、运行Go脚本
执行以下命令启动脚本:
go run ict2captable.go
运行后,输出日志显示三个corner在并行处理:
> go run ict2captable.go
cmd(2) start...
cmd(0) start...
cmd(1) start...
通过系统监控工具(如top)可以直观观察到并行执行的效果。


|