操作系统-生产者消费者实现-goalng语言

生产者消费者问题,是操作系统中的互斥问题。缓冲区是临界资源,每个运行实体(进程或线程)的访问缓冲区的代码是临界区。要确保最多只能有一个人访问临界资源,否则可能会出问题。

生产者或消费者可以有一个或多个。生产者每次生产一个产品,并试图放入缓冲区,如果缓冲区满,则等待。消费者每次试图从缓冲区拿一个产品并消费,如果缓冲区空,则等待。

任何进程在操作缓冲区时,会加锁,此时如果有其它进程试图访问,需要等待当前进程操作完成并释放锁。

C 语言实现 TODO

pthread 库实现了对线程的支持,编译时需要通过 -pthread 参数指定加载此库。

// 创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);
// 阻塞等待线程结束,成功结束时立刻返回0
int pthread_join(pthread_t thread, void **retval);

// 退出当前线程
void pthread_exit(void *retval);

golang 实现

golang 作为一门高级语言,内置的 channel 类型可以实现线程安全。当然也可以用 Mutex 加锁来实现。

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup
var buffer chan int
var buf_size int = 3

func main() {
          
   
	fmt.Println("main start")
	buffer = make(chan int, buf_size)
	wg.Add(2)
	go producer()
	go consumer()
	fmt.Println("all running")
	wg.Wait()
	fmt.Println("main end")
}

func producer() {
          
   
	for i := 0; i < buf_size * 5; i++ {
          
   
		fmt.Printf("producer make %d product
", i)
		if len(buffer) == buf_size {
          
   
		    fmt.Printf("====buffer full===
")
		}
		buffer <- i
		fmt.Printf("producer put %d product
", i)
	}
	fmt.Println("producer end")
	wg.Done()
}

func consumer() {
          
   
	for i := 0; i < buf_size * 5; i++ {
          
   
		fmt.Printf("			consumer consume %d product
", i)
		if len(buffer) == 0 {
          
   
		    fmt.Printf("			====buffer empty===
")
		}
		fmt.Printf("			consumer get %d product
", <-buffer)
	}
	fmt.Println("			consumer end")
	wg.Done()
}
经验分享 程序员 微信小程序 职场和发展