资源管理避免竞态条件
- 锁机制:使用互斥锁(Mutex)来保护共享资源。在访问共享资源前加锁,访问完成后解锁。例如在Go语言中:
package main
import (
"fmt"
"sync"
"time"
)
var (
mu sync.Mutex
count int
)
func task1() {
for {
mu.Lock()
count++
fmt.Println("Task1 incremented count:", count)
mu.Unlock()
time.Sleep(time.Second)
}
}
func task2() {
for {
mu.Lock()
count--
fmt.Println("Task2 decremented count:", count)
mu.Unlock()
time.Sleep(2 * time.Second)
}
}
- 读写锁(RWMutex):如果共享资源读操作远多于写操作,可以使用读写锁。读操作可以并发进行,写操作时加写锁,禁止其他读写操作。
package main
import (
"fmt"
"sync"
"time"
)
var (
rwmu sync.RWMutex
value int
)
func readTask() {
for {
rwmu.RLock()
fmt.Println("Read value:", value)
rwmu.RUnlock()
time.Sleep(time.Second)
}
}
func writeTask() {
for {
rwmu.Lock()
value++
fmt.Println("Write value:", value)
rwmu.Unlock()
time.Sleep(2 * time.Second)
}
}
- 通道(Channel):通过通道来传递对共享资源的操作请求,由一个专门的协程负责处理这些请求,从而避免竞态条件。
package main
import (
"fmt"
"sync"
"time"
)
type Request struct {
op string
data int
}
func resourceHandler(requests chan Request) {
var value int
for req := range requests {
switch req.op {
case "read":
fmt.Println("Read value:", value)
case "write":
value = req.data
fmt.Println("Write value:", value)
}
}
}
func readTask(requests chan Request) {
for {
requests <- Request{op: "read"}
time.Sleep(time.Second)
}
}
func writeTask(requests chan Request) {
for {
requests <- Request{op: "write", data: 1}
time.Sleep(2 * time.Second)
}
}
定时任务性能优化
- 减少锁的持有时间:只在真正需要访问共享资源时加锁,尽快解锁。
- 合理设置定时任务间隔:避免过于频繁的任务调度,减少系统开销。
- 异步处理:对于一些可以异步执行的操作,使用异步方式处理,如将数据库写操作放入队列,由专门的协程处理。
- 连接池复用:对于数据库连接池等资源,合理设置连接池大小,提高连接复用率。
完整代码示例
package main
import (
"fmt"
"sync"
"time"
)
// 共享资源
type SharedResource struct {
data int
mu sync.Mutex
}
// 定时任务1
func task1(resource *SharedResource, wg *sync.WaitGroup) {
defer wg.Done()
for {
resource.mu.Lock()
resource.data++
fmt.Println("Task1 incremented data:", resource.data)
resource.mu.Unlock()
time.Sleep(time.Second)
}
}
// 定时任务2
func task2(resource *SharedResource, wg *sync.WaitGroup) {
defer wg.Done()
for {
resource.mu.Lock()
resource.data--
fmt.Println("Task2 decremented data:", resource.data)
resource.mu.Unlock()
time.Sleep(2 * time.Second)
}
}
func main() {
var wg sync.WaitGroup
resource := &SharedResource{}
wg.Add(2)
go task1(resource, &wg)
go task2(resource, &wg)
wg.Wait()
}