Go与Python多线程竞争条件解析及加锁解决方案
本文通过Go和Python代码实例,演示多线程同时修改全局变量时产生的数据竞争问题。未加锁时结果远低于预期,引入互斥锁后确保数据一致性。文章对比了两种语言在并发控制上的实现差异,提供基础加锁代码参考。
Go与Python线程详解及简单实例
在Go语言中,启动15个协程(线程),每个协程对全局变量进行100000次累加操作,理论预期结果为15乘以100000,即1500000。
var sum int
var cccc int
var m *sync.Mutex
func Count1(i int, ch chan int) {
for j := 0; j < 100000; j++ {
cccc = cccc + 1
}
ch <- cccc
}
func main() {
m = new(sync.Mutex)
ch := make(chan int, 15)
for i := 0; i < 15; i++ {
go Count1(i, ch)
}
for i := 0; i < 15; i++ {
select {
case msg := <-ch:
fmt.Println(msg)
}
}
}
然而实际运行结果仅为406527。
这表明存在并发竞争条件,必须引入锁机制。
func Count1(i int, ch chan int) {
m.Lock()
for j := 0; j < 100000; j++ {
cccc = cccc + 1
}
ch <- cccc
m.Unlock()
}
引入锁机制后的最终输出结果为1500000。
在Python中采用相同逻辑实现,结果同样不正确。
count = 0
def sumCount(temp):
global count
for i in range(temp):
count = count + 1
li = []
for i in range(15):
th = threading.Thread(target=sumCount, args=(1000000,))
th.start()
li.append(th)
for i in li:
i.join()
print(count)
Python未加锁时的输出结果为3004737。
说明Python多线程环境下同样需要加锁保护:
mutex = threading.Lock()
count = 0
def sumCount(temp):
global count
mutex.acquire()
for i in range(temp):
count = count + 1
mutex.release()
li = []
for i in range(15):
th = threading.Thread(target=sumCount, args=(1000000,))
th.start()
li.append(th)
for i in li:
i.join()
print(count)
加锁后的输出结果为1500000。
以上即为加锁处理的简单示例。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









