当前位置: 首页 > news >正文

网站制作公司的网站厦门制作公司网站哪家好

网站制作公司的网站,厦门制作公司网站哪家好,写网页代码的软件,南山电商网站建设文章目录 互斥锁: sync.Mutexsync.WaitGroup 计数器例子func (*WaitGroup) Addfunc (*WaitGroup) Donefunc (*WaitGroup) Wait 读写互斥锁参考资料 临界区总是需要通过同步机制进行保护的,否则就会产生竞态条件,导致数据不一致。 互斥锁&…

文章目录

  • 互斥锁: sync.Mutex
  • sync.WaitGroup 计数器
    • 例子
    • func (*WaitGroup) Add
    • func (*WaitGroup) Done
    • func (*WaitGroup) Wait
  • 读写互斥锁
  • 参考资料

临界区总是需要通过同步机制进行保护的,否则就会产生竞态条件,导致数据不一致。

互斥锁: sync.Mutex

一个互斥锁可以被用来保护一个临界区,我们可以通过它来保证在同一时刻只有一个 goroutine 处于该临界区之内(同一个时刻只有一个线程能够拿到锁)

先通过一个并发读写的例子演示一下,当多线程同时访问全局变量时,结果会怎样?

package mainimport ("fmt"
)var count intfunc main() {for i := 0; i < 2; i++ {go func() {for i := 1000000; i > 0; i-- {count++}fmt.Println(count)}()}fmt.Scanf("\n") //等待子线程全部结束
}//运行结果
//1003065
//1033207

修改代码,在累加的地方添加互斥锁,就能保证我们每次得到的结果都是想要的值

package mainimport ("fmt""sync"
)var (count intlock  sync.Mutex
)func main() {for i := 0; i < 2; i++ {go func() {for i := 1000000; i > 0; i-- {lock.Lock()count++lock.Unlock()}fmt.Println(count)}()}fmt.Scanf("\n") //等待子线程全部结束
}// 运行结果
//1991307
//2000000

每当有 goroutine 想进入临界区时,都需要先对它进行锁定,并且,每个 goroutine 离开临界区时,都要及时地对它进行解锁,锁定和解锁操作分别通过互斥锁 sync.Mutex 的 Lock 和 Unlock 方法实现。使用互斥锁的时候有以下注意事项:

  • 不要重复锁定互斥锁;
  • 不要忘记解锁互斥锁,必要时使用 defer 语句;
  • 不要对尚未锁定或者已解锁的互斥锁解锁;
  • 不要在多个函数之间直接传递互斥锁。

sync.WaitGroup 计数器

type WaitGroup struct {// contains filtered or unexported fields// 包含已筛选或未导出的字段
}

A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.

WaitGroup等待goroutines的集合完成。主goroutine调用Add来设置要等待的goroutine的数量。然后,每个goroutine都会运行,并在完成时调用Done。同时,可以使用Wait来阻止,直到所有goroutine都完成。

A WaitGroup must not be copied after first use.
首次使用后不得复制WaitGroup。

In the terminology of the Go memory model, a call to Done “synchronizes before” the return of any Wait call that it unblocks.
在Go内存模型的术语中,对Done的调用在其取消阻止的任何Wait调用返回之前“同步”。

例子

This example fetches several URLs concurrently, using a WaitGroup to block until all the fetches are complete.
此示例同时获取多个URL,使用WaitGroup进行阻止,直到所有获取完成。

package mainimport ("sync"
)type httpPkg struct{}func (httpPkg) Get(url string) {}var http httpPkgfunc main() {var wg sync.WaitGroupvar urls = []string{"http://www.csdn.net/","http://www.youku.com/","http://www.baidu.com/",}for _, url := range urls {// Increment the WaitGroup counter.// 增加WaitGroup计数器。wg.Add(1)// Launch a goroutine to fetch the URL.// 启动goroutine以获取URL。go func(url string) {// Decrement the counter when the goroutine completes.// goroutine完成时递减计数器。defer wg.Done()// Fetch the URL.// 获取URL。http.Get(url)}(url)}// Wait for all HTTP fetches to complete.// 等待所有HTTP获取完成。wg.Wait()
}

func (*WaitGroup) Add

func (wg *WaitGroup) Add(delta int)

Add adds delta, which may be negative, to the WaitGroup counter. If the counter becomes zero, all goroutines blocked on Wait are released. If the counter goes negative, Add panics.

Add向WaitGroup计数器添加可能为负数的delta。如果计数器变为零,则会释放在Wait上阻止的所有goroutines。如果计数器为负数,Add会恐慌。

Note that calls with a positive delta that occur when the counter is zero must happen before a Wait. Calls with a negative delta, or calls with a positive delta that start when the counter is greater than zero, may happen at any time.

请注意,计数器为零时发生的具有正增量的调用必须在等待之前发生。任何时候都可能发生具有负增量的调用,或当计数器大于零时开始的具有正增量的调用。

Typically this means the calls to Add should execute before the statement creating the goroutine or other event to be waited for. If a WaitGroup is reused to wait for several independent sets of events, new Add calls must happen after all previous Wait calls have returned. See the WaitGroup example.

通常,这意味着对Add的调用应该在创建goroutine或其他待等待事件的语句之前执行。如果重用一个WaitGroup来等待多个独立的事件集,则必须在所有以前的wait调用都返回后进行新的Add调用。请参阅WaitGroup示例。

func (*WaitGroup) Done

func (wg *WaitGroup) Done()

Done decrements the WaitGroup counter by one.
Done将WaitGroup计数器递减一。

func (*WaitGroup) Wait

func (wg *WaitGroup) Wait()

Wait blocks until the WaitGroup counter is zero.
等待块,直到WaitGroup计数器为零。

读写互斥锁

互斥锁是完全互斥的,但是有很多实际的场景下是读多写少的,当我们并发的去读取一个资源不涉及资源修改的时候是没有必要加锁的,这种场景下使用读写锁是更好的一种选择。读写锁在Go语言中使用sync包中的RWMutex类型。

读写锁分为两种:读锁和写锁。当一个goroutine获取读锁之后,其他的goroutine如果是获取读锁会继续获得锁,如果是获取写锁就会等待;当一个goroutine获取写锁之后,其他的goroutine无论是获取读锁还是写锁都会等待。

读写锁示例:

package mainimport ("fmt""sync""time"
)var (x      int64wg     sync.WaitGrouplock   sync.Mutexrwlock sync.RWMutex
)func write() {// lock.Lock()   // 加互斥锁rwlock.Lock() // 加写锁x = x + 1time.Sleep(10 * time.Millisecond) // 假设读操作耗时10毫秒rwlock.Unlock()                   // 解写锁// lock.Unlock()                     // 解互斥锁wg.Done()
}func read() {// lock.Lock()                  // 加互斥锁rwlock.RLock()               // 加读锁time.Sleep(time.Millisecond) // 假设读操作耗时1毫秒rwlock.RUnlock()             // 解读锁// lock.Unlock()                // 解互斥锁wg.Done()
}func main() {start := time.Now()for i := 0; i < 10; i++ {wg.Add(1)go write()}for i := 0; i < 1000; i++ {wg.Add(1)go read()}wg.Wait()end := time.Now()fmt.Println(end.Sub(start))
}// 173.3553ms

参考资料

sync包
golang并发之sync包

http://www.yayakq.cn/news/323799/

相关文章:

  • 高端网站开发哪家强vipkid网站开发团队
  • 定制化网站建设公司山东网站建设公司哪家专业
  • 网站版权文字鹤山做网站
  • 建设企业网站怎样收费网页和网站有什么区别
  • 网站flash效果南宁排名推广
  • 网站制作公司咨询工作内容如何做h5商城网站
  • 优秀的展厅设计网站js特效网站欣赏
  • 物流网站公司外链发布平台有哪些
  • 建设建材网站中山网站建设中山
  • 宿州网站网站建设优秀版式设计
  • 网站的服务内容代做动画毕业设计的网站
  • 为什么要做官方网站北京最大的网站建设有限公司
  • 甘肃购物网站建设淄博那里有做网站的
  • 做网络销售哪些网站比较好wordpress+关闭warning
  • 网站开发的分工道滘东莞微信网站建设
  • 优秀茶叶网站设计外贸免费网站建设
  • 字号 wordpress瑞安网站建设优化
  • 衡水网站建设制作wordpress不用插件
  • 网站建设的必要性’wordpress 拼团插件
  • 专做山珍的网站教育机构域名
  • 产品免费推广网站有哪些动画设计电脑配置要求
  • 东莞中英文网站建设国外优秀产品设计作品欣赏
  • 软件培训网站大数据网站
  • 广州做网站哪间公司好购物网站创业时是如何做宣传的
  • 学风建设网站app拉新推广平台渠道
  • 上海网站seo设计如何让自己做的网站让别人看到
  • 北京市朝阳区官方发布百度seo代理
  • 网站开发员工作职责鄂尔多斯网站开发
  • 嘉兴专业网站排名推广手机怎么防止网站跳转
  • 360房产网徐州seo培训