医院内外网站建设,怎么做英文版网站,锡山建设局网站,营销型网站建设及推广信号量 信号量的本质是一个计数器#xff0c;可以用来衡量临界资源中资源数量多少 信号量的PV操作 P操作#xff1a;申请信号量称为P操作#xff0c;P操作的本质就是让计数器减1。 V操作#xff1a;释放信号量称为V操作#xff0c;V操作的本质就是让计数器加1 POSIX信号量…信号量 信号量的本质是一个计数器可以用来衡量临界资源中资源数量多少 信号量的PV操作 P操作申请信号量称为P操作P操作的本质就是让计数器减1。 V操作释放信号量称为V操作V操作的本质就是让计数器加1 POSIX信号量相关的接口函数
初始化信号量
int sem_init(sem_t *sem, int pshared, unsigned int value); sem需要初始化的信号量。 pshared0表示线程间共享非0表示进程间共享。 value信号量的初始值特定资源的初始数量。 等待信号量P操作)
int sem_wait(sem_t *sem);
发布信号量V操作)
int sem_post(sem_t *sem);
销毁信号量
int sem_destroy(sem_t *sem);
基于环形队列的生产消费模型代码 RingQueue.hpp
#pragma once#include iostream
#include vector
#include cassert
#include semaphore.h
#include pthread.hstatic const int gcap 5;templateclass T
class RingQueue
{
private:void P(sem_t sem){int n sem_wait(sem);assert(n 0); // if(void)n;}void V(sem_t sem){int n sem_post(sem);assert(n 0);(void)n;}
public:RingQueue(const int cap gcap): _queue(cap), _cap(cap){int n sem_init(_spaceSem, 0, _cap);assert(n 0);n sem_init(_dataSem, 0, 0);assert(n 0);_productorStep _consumerStep 0;pthread_mutex_init(_pmutex, nullptr);pthread_mutex_init(_cmutex, nullptr);}// 生产者void Push(const T in){//先申请信号量在加锁P(_spaceSem); pthread_mutex_lock(_pmutex); _queue[_productorStep] in;_productorStep % _cap;pthread_mutex_unlock(_pmutex);V(_dataSem);}// 消费者void Pop(T *out){//先申请信号量在加锁P(_dataSem);pthread_mutex_lock(_cmutex);*out _queue[_consumerStep];_consumerStep % _cap;pthread_mutex_unlock(_cmutex);V(_spaceSem);}~RingQueue(){sem_destroy(_spaceSem);sem_destroy(_dataSem);pthread_mutex_destroy(_pmutex);pthread_mutex_destroy(_cmutex);}
private:std::vectorT _queue;int _cap;sem_t _spaceSem; // 生产者的空间资源sem_t _dataSem; // 消费者的数据资源int _productorStep;int _consumerStep;pthread_mutex_t _pmutex;pthread_mutex_t _cmutex;
};
Task.hpp
#pragma once#include iostream
#include string
#include cstdio
#include functionalclass Task
{using func_t std::functionint(int,int,char);// typedef std::functionint(int,int) func_t;
public:Task(){}Task(int x, int y, char op, func_t func):_x(x), _y(y), _op(op), _callback(func){}std::string operator()(){int result _callback(_x, _y, _op);char buffer[1024];snprintf(buffer, sizeof buffer, %d %c %d %d, _x, _op, _y, result);return buffer;}std::string toTaskString(){char buffer[1024];snprintf(buffer, sizeof buffer, %d %c %d ?, _x, _op, _y);return buffer;}
private:int _x;int _y;char _op;func_t _callback;
};const std::string oper -*/%;int mymath(int x, int y, char op)
{int result 0;switch (op){case :result x y;break;case -:result x - y;break;case *:result x * y;break;case /:{if (y 0){std::cerr div zero error! std::endl;result -1;}elseresult x / y;}break;case %:{if (y 0){std::cerr mod zero error! std::endl;result -1;}elseresult x % y;}break;default:// do nothingbreak;}return result;
}
main.cc
#include RingQueue.hpp
#include Task.hpp
#include pthread.h
#include ctime
#include cstdlib
#include sys/types.h
#include unistd.hstd::string SelfName()
{char name[128];snprintf(name, sizeof(name), thread[0x%x], pthread_self());return name;
}void *ProductorRoutine(void *rq)
{RingQueueTask *ringqueue static_castRingQueueTask *(rq);while(true){int x rand() % 10;int y rand() % 5;char op oper[rand()%oper.size()];Task t(x, y, op, mymath);// 生产任务ringqueue-Push(t);// 输出提示std::cout SelfName() , 生产者派发了一个任务: t.toTaskString() std::endl;sleep(1);}
}void *ConsumerRoutine(void *rq)
{RingQueueTask *ringqueue static_castRingQueueTask *(rq);while(true){Task t;//消费任务ringqueue-Pop(t);std::string result t(); std::cout SelfName() , 消费者消费了一个任务: result std::endl;}
}int main()
{srand((unsigned int)time(nullptr) ^ getpid() ^ pthread_self() ^ 0x71727374);RingQueueTask *rq new RingQueueTask();pthread_t p[4], c[8];for(int i 0; i 4; i) pthread_create(pi, nullptr, ProductorRoutine, rq);for(int i 0; i 8; i) pthread_create(ci, nullptr, ConsumerRoutine, rq);for(int i 0; i 4; i) pthread_join(p[i], nullptr);for(int i 0; i 8; i) pthread_join(c[i], nullptr);delete rq;return 0;
}
测试结果