Dijkstra (1965) 信号量 demo使用 golang实现

11 篇文章 1 订阅
8 篇文章 0 订阅
  • Dijkstra (1965) 引入了信号量的概念
  • 信号量是一个整数变量,可通过两个标准原子操作访问:等待(自旋锁,即停止阻塞并递减这些信号量)和信号量(即信号量计算它接收到的信号)
  • 信号量是用于向进程发送共享资源状态信号的变量(信号量的值可以为 0,表示没有保存唤醒,或者如果有一个或多个唤醒处于未决状态,则为某个正值)
  • 这是如何运作的?
    • 如果资源不可用,则相应的信号量会阻塞任何等待该资源的进程
    • 阻塞的进程被放入由信号量维护的进程队列中(避免忙等待!)
    • 当进程释放资源时,它通过信号量发出信号
    • 如果有任何信号,则恢复阻塞的进程
    • 等待和信号操作不能被中断
    • 复杂的协调可以由多个信号量指定
  • 信号量的向下操作
    • 检查值是否大于 0
    • 如果是这样,它会减少值并继续
    • 如果值为 0,则进程进入睡眠状态,暂时 不完成down
    • 一切都是作为一个单一的、不可分割的原子动作完成的
      • 检查值
      • 改变它
      • 可能要睡觉了
    • 保证一旦信号量操作开始,在操作完成之前没有其他进程可以访问信号量
    • 同步和无竞争条件
  • 信号量上的up操作
    • 增加信号量的值
    • 如果一个或多个进程在该信号量上休眠,无法完成较早的关闭操作,则系统选择其中一个并允许完成其关闭
    • 信号量将为 0。但会少一个进程在其上休眠
    • 不可分割的过程;增加信号量并唤醒一个进程
  • 使用信号量解决生产者-消费者问题(见图2.14
    • 该解决方案使用三个信号量;
      • 一个称为full用于计算已满的插槽数
      • 一种称为的,用于计算空槽的数量
      • 一种称为互斥锁以确保生产者和消费者不会同时访问缓冲区。mutex最初为 1(二进制信号量
      • 如果每个进程在进入它的 CR 之前执行一次down并在离开它之后执行一次up,则保证互斥。
  • 信号量的可能用途;
    • 互斥,初始化信号量为1
    • 协同进程(信令)的同步,将信号量初始化为零
    • 管理一个资源的多个实例,将信号量初始化为实例数
  • 信号量的类型;
    • binary是一个 0 和 1 整数值的信号量。
    • 计数是一个信号量,其整数值介于 0 和任意大数之间。它的初始值可能表示可用​​的关键资源的单位数。这种形式也称为通用信号量。

Semaphores

  • Dijkstra (1965) introduced the concept of a semaphore
  • A semaphore is an integer variable that is accessed through two standard atomic operations: wait ( a spinlock, i.e. stops blocking and decrements thesemaphore) and signal (i.e. the semaphore counts the signals it receives)
  • Semaphores are variables that are used to signal the status of shared resources to processes (a semaphore could have the value of 0, indicating that no wakeups are saved, or some positive value if one or more wakeups are pending)
  • How does that work?
    • If a resource is not available, the corresponding semaphore blocks any process waiting for the resource
    • Blocked processes are put into a process queue maintained by the semaphore (avoids busy waiting!)
    • When a process releases a resource, it signals this by means of the semaphore
    • Signalling resumes a blocked process if there is any
    • Wait and signal operations cannot be interrupted
    • Complex coordination can be specified by multiple semaphores
  • the down operation on a semaphore
    • checks to see if the value is greater than 0
    • if so, it decrements the value and continues
    • if the value is 0, the process is put to sleep without the completing the down for the moment
    • all is done as a single, indivisible atomic action
      • checking the value
      • changing it
      • possibly going to sleep
    • it is guaranteed that once a semaphore operation has started, no other process can access the semaphore until the operation has completed
    • synchronization and no race condition
  • the up operation on a semaphore
    • increments the value of the semaphore
    • if one or more processes were sleeping on that semaphore, unable to complete an earlier down operation, one of them is chosen by the system and allowed to complete its down
    • the semaphore will be 0. but there will be one fewer process sleeping on it
    • indivisible process; incrementing the semaphore and waking up one process
  • Solving the producer-consumer problem using semaphores (see Fig. 2.14)
    • the solution uses three semaphores;
      • one called full for counting the number of slots that are full
      • one called empty for counting the number of slots that are empty
      • one called mutex to make sure the producer and the consumer do not access the buffer at the same time. mutex is initially 1 (binary semaphore)
      • if each process does a down just before entering its CR and an up just after leaving it, the mutual exclusion is guaranteed.
  • Possible uses of semaphores;
    • Mutual exclusion, initialize the semaphore to one
    • Synchronization of cooperating processes (signaling), initialize the semaphore to zero
    • Managing multiple instances of a resource, initialize the semaphore to the number of instances
  • Type of semaphores;
    • binary is a semaphore with an integer value of 0 and 1.
    • counting is a semaphore with an integer value ranging between 0 and an arbitrarily large number. Its initial value might represent the number of units of the critical resources that are available. This form is also known as a general semaphore.

golang 模拟信号量实现

主要代码:

const N = 1

var mutex int64 = 1
var empty int64 = N
var full int64 = 0

func Producer() {

	var item int
	for {
		item = producer_item()
		down(&empty, "Producer empty")
		down(&mutex, "Producer mutex")
		insert_item(item)
		
		up(&mutex, "Producer mutex")
		up(&full, "Producer full")
	}
}
func Consumer() {
	var item int
	for {
		down(&full, "Consumer full")
		down(&mutex, "Consumer mutex")
		item = item_remove_item()
		testRace(item, 2)
		up(&mutex, "Consumer mutex")
		up(&empty, "Consumer empty")
		consumer_item(item)
	}
}

N= 1

package semaphore

import (
	"container/list"
	"sync/atomic"
	"time"
)

const N = 1

var mutex int64 = 1
var empty int64 = N
var full int64 = 0
var testMap = map[int]int{}

func Producer() {

	var item int
	for {
		item = producer_item()
		down(&empty, "Producer empty")
		//down(&mutex, "Producer mutex")
		insert_item(item)
		testRace(item, 1)
		//up(&mutex, "Producer mutex")
		up(&full, "Producer full")
	}
}
func testRace(item int, value int) {
	testMap[item] = value
}
func Consumer() {
	var item int
	for {
		down(&full, "Consumer full")
		//down(&mutex, "Consumer mutex")
		item = item_remove_item()
		testRace(item, 2)
		//up(&mutex, "Consumer mutex")
		up(&empty, "Consumer empty")
		consumer_item(item)
	}
}

var items list.List
var i = 0

func producer_item() int {
	i++
	println("producer_item item:", i)
	return i
}

func consumer_item(item int) {
	println("consumer_item item:", item)
}

func insert_item(item int) {
	items.PushBack(item)
	println("insert_item:", item)
}

func item_remove_item() int {
	length := items.Len()
	front := items.Front()
	items.Remove(front)
	tmp := front.Value.(int)
	println("item_remove_item:", tmp, "length:", length)
	return tmp
}

func down(v *int64, tag string) {
	for *v <= 0 {
		time.Sleep(1)
		println("down: wait... *v <= 0 ,*v:", *v, "tag:", tag)
	}
	old := *v
	t := atomic.AddInt64(v, -1)
	println("down:", t, "old:", old, "tag:", tag)
}

func up(v *int64, tag string) {
	old := *v
	t := atomic.AddInt64(v, 1)
	println("up:", t, "old:", old, "tag:", tag)
}

调用main

func main() {
	go semaphore.Producer()
	go semaphore.Consumer()

	time.Sleep(30 * time.Millisecond)

	println("main finished")
}

临界资源为1

所以运行没有问题:

结果如下:

。。。
insert_item: 348
up: 1 old: 0 tag: Producer full
producer_item item: 349
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 348 length: 1
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 349
up: 1 old: 0 tag: Producer full
producer_item item: 350
up: 1 old: 0 tag: Consumer empty
consumer_item item: 348
down: 0 old: 1 tag: Consumer full
item_remove_item: 349 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 349
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 350
up: 1 old: 0 tag: Producer full
producer_item item: 351
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 350 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 350
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 351
up: 1 old: 0 tag: Producer full
producer_item item: 352
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 351 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 351
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 352
up: 1 old: 0 tag: Producer full
producer_item item: 353
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 352 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 352
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 353
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
up: 1 old: 0 tag: Producer full
producer_item item: 354
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: wait... *v <= 0 ,*v: 1 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 353 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 353
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 354
up: 1 old: 0 tag: Producer full
producer_item item: 355
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 354 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 354
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 355
up: 1 old: 0 tag: Producer full
producer_item item: 356
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 355 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 355
down: wait... *v <= 0 ,*v: 0 tag: Producer empty
down: 0 old: 1 tag: Producer empty
insert_item: 356
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 0 old: 1 tag: Consumer full
item_remove_item: 356 length: 1
up: 1 old: 0 tag: Consumer empty
consumer_item item: 356
up: 1 old: 0 tag: Producer full
producer_item item: 357
down: 0 old: 1 tag: Producer empty
main finished
insert_item: 357
up: 1 old: 0 tag: Producer full
producer_item item: 358

并发修改问题:调整N= 300

const N = 300

理论因为,empty信号量为300,生产和消费会并发修改。

报错如下:

down: 17 old: 18 tag: Consumer full
item_remove_item: 404 length: 18
up: 283 old: 282 tag: Consumer empty
consumer_item item: 404
up: 20 old: 19 tag: Producer full
producer_item item: 422
down: 282 old: 283 tag: Producer empty
down: 16 old: 17 tag: Consumer full
item_remove_item: 405 length: 18
up: 283 old: 282 tag: Consumer empty
consumer_item item: 405
down: 15 old: 16 tag: Consumer full
item_remove_item: 406 length: 17
insert_item: 422
fatal error: concurrent map writes

goroutine 5 [running]:
runtime.throw({0x10674ec, 0x10664a0})
        /Users/edz/.g/versions/1.17.6/src/runtime/panic.go:1198 +0x71 fp=0xc00003a768 sp=0xc00003a738 pc=0x102c331
runtime.mapassign_fast64(0x10c3188, 0x10664a0, 0x1a6)
        /Users/edz/.g/versions/1.17.6/src/runtime/map_fast64.go:101 +0x2c5 fp=0xc00003a7a0 sp=0xc00003a768 pc=0x100da05
gopl.io/demo/semaphore.testRace(...)
        /Users/edz/gostudy/gopl.io/demo/semaphore/semaphore.go:30
gopl.io/demo/semaphore.Producer()
        /Users/edz/gostudy/gopl.io/demo/semaphore/semaphore.go:24 +0x96 fp=0xc00003a7e0 sp=0xc00003a7a0 pc=0x1057cd6
runtime.goexit()
        /Users/edz/.g/versions/1.17.6/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc00003a7e8 sp=0xc00003a7e0 pc=0x1053921
created by main.main
        /Users/edz/gostudy/gopl.io/demo/semaphore/main/main.go:9 +0x25

goroutine 1 [sleep]:
time.Sleep(0x1c9c380)
        /Users/edz/.g/versions/1.17.6/src/runtime/time.go:193 +0x12e
main.main()
        /Users/edz/gostudy/gopl.io/demo/semaphore/main/main.go:12 +0x3d

goroutine 6 [runnable]:
gopl.io/demo/semaphore.testRace(...)
        /Users/edz/gostudy/gopl.io/demo/semaphore/semaphore.go:30
gopl.io/demo/semaphore.Consumer()
        /Users/edz/gostudy/gopl.io/demo/semaphore/semaphore.go:38 +0x51
created by main.main
        /Users/edz/gostudy/gopl.io/demo/semaphore/main/main.go:10 +0x33

Process finished with the exit code 2

恢复mutex:每次product和customer的信号量mutex

func Producer() {

	var item int
	for {
		item = producer_item()
		down(&empty, "Producer empty")
		down(&mutex, "Producer mutex")
		insert_item(item)
		testRace(item, 1)
		up(&mutex, "Producer mutex")
		up(&full, "Producer full")
	}
}
func testRace(item int, value int) {
	testMap[item] = value
}
func Consumer() {
	var item int
	for {
		down(&full, "Consumer full")
		down(&mutex, "Consumer mutex")
		item = item_remove_item()
		testRace(item, 2)
		up(&mutex, "Consumer mutex")
		up(&empty, "Consumer empty")
		consumer_item(item)
	}
}

结果正常:

insert_item: 298
down: wait... *v <= 0 ,*v: 0 tag: Consumer mutex
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 269 length: 30
up: 1 old: 0 tag: Consumer mutex
up: 271 old: 270 tag: Consumer empty
consumer_item item: 269
down: 27 old: 28 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 270 length: 29
up: 1 old: 0 tag: Consumer mutex
up: 272 old: 271 tag: Consumer empty
consumer_item item: 270
down: 26 old: 27 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 271 length: 28
up: 1 old: 0 tag: Consumer mutex
up: 273 old: 272 tag: Consumer empty
consumer_item item: 271
down: 25 old: 26 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 272 length: 27
up: 1 old: 0 tag: Consumer mutex
up: 274 old: 273 tag: Consumer empty
consumer_item item: 272
down: 24 old: 25 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 273 length: 26
up: 1 old: 0 tag: Consumer mutex
up: 275 old: 274 tag: Consumer empty
consumer_item item: 273
down: 23 old: 24 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 274 length: 25
up: 1 old: 0 tag: Consumer mutex
up: 276 old: 275 tag: Consumer empty
consumer_item item: 274
down: 22 old: 23 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 275 length: 24
up: 1 old: 0 tag: Consumer mutex
up: 277 old: 276 tag: Consumer empty
consumer_item item: 275
down: 21 old: 22 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 276 length: 23
up: 1 old: 0 tag: Consumer mutex
up: 278 old: 277 tag: Consumer empty
consumer_item item: 276
down: 20 old: 21 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 277 length: 22
up: 1 old: 0 tag: Consumer mutex
up: 279 old: 278 tag: Consumer empty
consumer_item item: 277
down: 19 old: 20 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 278 length: 21
up: 1 old: 0 tag: Consumer mutex
up: 280 old: 279 tag: Consumer empty
consumer_item item: 278
down: 18 old: 19 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 279 length: 20
up: 1 old: 0 tag: Consumer mutex
up: 281 old: 280 tag: Consumer empty
consumer_item item: 279
down: 17 old: 18 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 280 length: 19
up: 1 old: 0 tag: Consumer mutex
up: 282 old: 281 tag: Consumer empty
consumer_item item: 280
down: 16 old: 17 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 281 length: 18
up: 1 old: 0 tag: Consumer mutex
up: 283 old: 282 tag: Consumer empty
consumer_item item: 281
down: 15 old: 16 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 282 length: 17
up: 1 old: 0 tag: Consumer mutex
up: 284 old: 283 tag: Consumer empty
consumer_item item: 282
down: 14 old: 15 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 283 length: 16
up: 1 old: 0 tag: Consumer mutex
up: 285 old: 284 tag: Consumer empty
consumer_item item: 283
down: 13 old: 14 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
up: 1 old: 0 tag: Producer mutex
up: 14 old: 13 tag: Producer full
producer_item item: 299
down: 284 old: 285 tag: Producer empty
item_remove_item: 284 length: 15
up: 1 old: 0 tag: Consumer mutex
up: 285 old: 284 tag: Consumer empty
consumer_item item: 284
down: 13 old: 14 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 285 length: 14
up: 1 old: 0 tag: Consumer mutex
up: 286 old: 285 tag: Consumer empty
consumer_item item: 285
down: 12 old: 13 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 286 length: 13
up: 1 old: 0 tag: Consumer mutex
up: 287 old: 286 tag: Consumer empty
consumer_item item: 286
down: 11 old: 12 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 287 length: 12
up: 1 old: 0 tag: Consumer mutex
up: 288 old: 287 tag: Consumer empty
consumer_item item: 287
down: 10 old: 11 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 288 length: 11
up: 1 old: 0 tag: Consumer mutex
up: 289 old: 288 tag: Consumer empty
consumer_item item: 288
down: 9 old: 10 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 289 length: 10
up: 1 old: 0 tag: Consumer mutex
up: 290 old: 289 tag: Consumer empty
consumer_item item: 289
down: 8 old: 9 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 290 length: 9
up: 1 old: 0 tag: Consumer mutex
up: 291 old: 290 tag: Consumer empty
consumer_item item: 290
down: 7 old: 8 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 291 length: 8
up: 1 old: 0 tag: Consumer mutex
up: 292 old: 291 tag: Consumer empty
consumer_item item: 291
down: 6 old: 7 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 292 length: 7
up: 1 old: 0 tag: Consumer mutex
up: 293 old: 292 tag: Consumer empty
consumer_item item: 292
down: 5 old: 6 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 293 length: 6
up: 1 old: 0 tag: Consumer mutex
up: 294 old: 293 tag: Consumer empty
consumer_item item: 293
down: 4 old: 5 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 294 length: 5
up: 1 old: 0 tag: Consumer mutex
up: 295 old: 294 tag: Consumer empty
consumer_item item: 294
down: 3 old: 4 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 295 length: 4
up: 1 old: 0 tag: Consumer mutex
up: 296 old: 295 tag: Consumer empty
consumer_item item: 295
down: 2 old: 3 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 296 length: 3
up: 1 old: 0 tag: Consumer mutex
up: 297 old: 296 tag: Consumer empty
consumer_item item: 296
down: 1 old: 2 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 297 length: 2
up: 1 old: 0 tag: Consumer mutex
up: 298 old: 297 tag: Consumer empty
consumer_item item: 297
down: 0 old: 1 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 298 length: 1
up: 1 old: 0 tag: Consumer mutex
up: 299 old: 298 tag: Consumer empty
consumer_item item: 298
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: wait... *v <= 0 ,*v: 0 tag: Producer mutex
down: 0 old: 1 tag: Producer mutex
insert_item: 299
up: 1 old: 0 tag: Producer mutex
up: 1 old: 0 tag: Producer full
producer_item item: 300
down: 298 old: 299 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 300
up: 1 old: 0 tag: Producer mutex
up: 2 old: 1 tag: Producer full
producer_item item: 301
down: 297 old: 298 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 301
up: 1 old: 0 tag: Producer mutex
up: 3 old: 2 tag: Producer full
producer_item item: 302
down: 296 old: 297 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 302
up: 1 old: 0 tag: Producer mutex
up: 4 old: 3 tag: Producer full
producer_item item: 303
down: 295 old: 296 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 303
up: 1 old: 0 tag: Producer mutex
up: 5 old: 4 tag: Producer full
producer_item item: 304
down: 294 old: 295 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 304
down: wait... *v <= 0 ,*v: 1 tag: Consumer full
down: 4 old: 5 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 299 length: 6
up: 1 old: 0 tag: Consumer mutex
up: 295 old: 294 tag: Consumer empty
consumer_item item: 299
down: 3 old: 4 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 300 length: 5
up: 1 old: 0 tag: Consumer mutex
up: 296 old: 295 tag: Consumer empty
consumer_item item: 300
down: 2 old: 3 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 301 length: 4
up: 1 old: 0 tag: Consumer mutex
up: 297 old: 296 tag: Consumer empty
consumer_item item: 301
down: 1 old: 2 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 302 length: 3
up: 1 old: 0 tag: Consumer mutex
up: 298 old: 297 tag: Consumer empty
consumer_item item: 302
down: 0 old: 1 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 303 length: 2
up: 1 old: 0 tag: Consumer mutex
up: 299 old: 298 tag: Consumer empty
consumer_item item: 303
up: 1 old: 0 tag: Producer mutex
up: 1 old: 0 tag: Producer full
producer_item item: 305
down: 298 old: 299 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 305
up: 1 old: 0 tag: Producer mutex
up: 2 old: 1 tag: Producer full
producer_item item: 306
down: 297 old: 298 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 306
up: 1 old: 0 tag: Producer mutex
up: 3 old: 2 tag: Producer full
producer_item item: 307
down: 296 old: 297 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 307
up: 1 old: 0 tag: Producer mutex
up: 4 old: 3 tag: Producer full
producer_item item: 308
down: 295 old: 296 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 308
up: 1 old: 0 tag: Producer mutex
up: 5 old: 4 tag: Producer full
producer_item item: 309
down: 294 old: 295 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 309
up: 1 old: 0 tag: Producer mutex
up: 6 old: 5 tag: Producer full
producer_item item: 310
down: 293 old: 294 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 310
up: 1 old: 0 tag: Producer mutex
up: 7 old: 6 tag: Producer full
producer_item item: 311
down: 292 old: 293 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 311
up: 1 old: 0 tag: Producer mutex
up: 8 old: 7 tag: Producer full
producer_item item: 312
down: 291 old: 292 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 312
down: wait... *v <= 0 ,*v: 0 tag: Consumer full
down: 7 old: 8 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 304 length: 9
up: 1 old: 0 tag: Consumer mutex
up: 292 old: 291 tag: Consumer empty
consumer_item item: 304
down: 6 old: 7 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 305 length: 8
up: 1 old: 0 tag: Consumer mutex
up: 293 old: 292 tag: Consumer empty
consumer_item item: 305
down: 5 old: 6 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 306 length: 7
up: 1 old: 0 tag: Consumer mutex
up: 294 old: 293 tag: Consumer empty
consumer_item item: 306
down: 4 old: 5 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 307 length: 6
up: 1 old: 0 tag: Consumer mutex
up: 295 old: 294 tag: Consumer empty
consumer_item item: 307
down: 3 old: 4 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 308 length: 5
up: 1 old: 0 tag: Consumer mutex
up: 296 old: 295 tag: Consumer empty
consumer_item item: 308
up: 1 old: 0 tag: Producer mutex
up: 3 old: 2 tag: Producer full
producer_item item: 313
down: 295 old: 296 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
down: 2 old: 3 tag: Consumer full
insert_item: 313
up: 1 old: 0 tag: Producer mutex
up: 4 old: 3 tag: Producer full
producer_item item: 314
down: 294 old: 295 tag: Producer empty
down: 0 old: 1 tag: Producer mutex
insert_item: 314
up: 1 old: 0 tag: Producer mutex
up: 5 old: 4 tag: Producer full
producer_item item: 315
down: wait... *v <= 0 ,*v: 1 tag: Consumer mutex
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 309 length: 6
up: 1 old: 0 tag: Consumer mutex
up: 294 old: 293 tag: Consumer empty
consumer_item item: 309
down: 4 old: 5 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 310 length: 5
up: 1 old: 0 tag: Consumer mutex
up: 295 old: 294 tag: Consumer empty
consumer_item item: 310
down: 3 old: 4 tag: Consumer full
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 311 length: 4
up: 1 old: 0 tag: Consumer mutex
up: 296 old: 295 tag: Consumer empty
consumer_item item: 311
down: 2 old: 3 tag: Consumer full
down: 293 old: 294 tag: Producer empty
down: wait... *v <= 0 ,*v: 0 tag: Producer mutex
down: wait... *v <= 0 ,*v: 0 tag: Producer mutex
down: 0 old: 1 tag: Consumer mutex
item_remove_item: 312 length: 3
down: wait... *v <= 0 ,*v: 0 tag: Producer mutex
down: 0 old: 1 tag: Producer mutex
main finished
up: 1 old: 0 tag: Consumer mutex
up: 297 old: 296 tag: Consumer empty
consumer_item item: 312
down: 1 old: 2 tag: Consumer full
insert_item: 315
up: 1 old: 
Process finished with the exit code 0

参考:

Semaphores

http://boron.physics.metu.edu.tr/ozdogan/OperatingSystems/spring2004/week4/week4.pdf

Golang 五种原子性操作的用法详解 - 云+社区 - 腾讯云

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值