sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,将信号量的值将减到1。如果对一个值为0的信号量调用sem_wait(),这个函数就会原地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加 一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。sem_trywait(sem_t *sem)是函数sem_wait的非阻塞版,它直接将信号量sem减1,同时返回错误代码。
/*基于信号量采用多线程技术实现进程同步*/#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/time.h>
#include <math.h>
#define CHAIRS 5 //椅子数
sem_t customers //等待服务的顾客信号量
sem_t barbers //等待顾客的理发师信号量
pthread_mutex_t mutex //互斥变量
int waiting = 0 //正在等待的顾客数
void *barber(void *arg)
void *customer(void *num)
void cut_hair(void)
double timediff(struct timeval i,struct timeval j)
void seed_random(void)
double flat(void)
double normal(void)
double bursty(void)
int main()
{
int i
seed_random()
pthread_t barber_t,customer_t
int error
error=pthread_create(&barber_t,NULL,barber,NULL)//创建理发师线程
if(error!=0) {
printf("pthread_create is not created.../n")
return -1
}
while(1) {
usleep(30000)//等待时间如果小于理发师理发时间则会出现等待者过多,否则不会出现等待者过多的现象
error=pthread_create(&customer_t,NULL,customer,NULL)//创建顾客线程
if(error!=0) {
printf("pthread_create is not created.../n")
return -1
}
}
}
double timediff(struct timeval now,struct timeval earlier)
{
if(now.tv_sec == earlier.tv_sec)
return (now.tv_usec - earlier.tv_usec)/1000000.0
else
return (1000000*(now.tv_sec - earlier.tv_sec) + now.tv_usec - earlier.tv_usec)/1000000.0
}
void *barber(void *arg)
{
while(1)
{
sem_wait(&customers)//顾客信号量-1
pthread_mutex_lock(&mutex)
waiting = waiting -1
sem_post(&barbers)//
pthread_mutex_unlock(&mutex)
cut_hair()//理发
}
}
void cut_hair(void)
{
printf(" Barber:I am cutting the customer's hair.../n")
usleep(100000)//理发时间
printf(" Barber:done./n")
}
void *customer(void *num)
{
pthread_mutex_lock(&mutex)
if(waiting<CHAIRS)
{
waiting = waiting + 1
sem_post(&customers)
pthread_mutex_unlock(&mutex)
sem_wait(&barbers)
}
else
{
printf(" Waiter is too much.../n")
pthread_mutex_unlock(&mutex)
}
//释放占用的资源
}
void seed_random(void)
{
struct timeval randtime
unsigned short xsub1[3]
gettimeofday(&randtime,(struct timezone *)0)
xsub1[0] = (ushort)randtime.tv_usec
xsub1[1] = (ushort)(randtime.tv_usec >> 16)
xsub1[2] = (ushort)(getpid())
seed48(xsub1)
}
double flat()
{
return drand48()/5
}
第二问 加个理发师忙碌数量 用来判断 即可
菜鸟实现耗时测试,勿喷
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <unistd.h>
#include <semaphore.h>
using namespace std
#define msleep(x) usleep(x*1000)
queue<int>queueIn
queue<int>queueOut
std::mutex threadMutex
int max_len = 4
int index = 0
static sem_t g_semaphore
static sem_t g_semaphore_queuOut
bool isEnd = false
void decoder() {
int i = 0
while (i <10000) {
if(queueIn.size() >max_len) {
continue
}
queueIn.push(i++)
}
while (index != 9999) {
}
isEnd = true
}
void encoder() {
int i = -1
while (!isEnd || !queueIn.empty()) {
i = -1
sem_wait(&g_semaphore)
if(!queueIn.empty()){
i = queueIn.front()
queueIn.pop()
}
sem_post(&g_semaphore)
if(i == -1){
continue
}
while (true){
if(i == 0){
break
}
//printf("index %d i %d\n",index,i)
if(i - index == 1){
break
}
}
sem_wait(&g_semaphore_queuOut)
queueOut.push(i)
if(i >index) {
index = i
}
sem_post(&g_semaphore_queuOut)
}
}
void enCoderH264() {
while (!isEnd || !queueOut.empty() || !queueIn.empty()) {
sem_wait(&g_semaphore_queuOut)
if(!queueOut.empty()){
int i = queueOut.front()
queueOut.pop()
printf("queueout %d \n",i)
}
sem_post(&g_semaphore_queuOut)
}
//printf("end %d \n",queueOut.size())
}
int main() {
sem_init(&g_semaphore, 0, 1)
sem_init(&g_semaphore_queuOut,0,1)
thread t(decoder)
thread t2(encoder)
thread t3(encoder)
thread t4(encoder)
thread t5(enCoderH264)
t.detach()
t2.detach()
t3.detach()
t4.detach()
t5.detach()
std::cout <<"Hello, World!" <<std::endl
pthread_exit(NULL)
return 0
}
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)