IPC 经典问题:Sleeping Barber Problem

完整代码实现:

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define CUSTOMER_NUMBER 20
void *customer(void *param);
void *barber(void *param);

int seat_num = 5;
int interval[CUSTOMER_NUMBER] = {100, 100, 200, 100, 250, 400, 200, 100, 200, 700, 100, 200, 600, 100, 250, 400, 200, 100, 200, 700};

sem_t cust_ready;
sem_t barber_ready;
sem_t mutex;

int main(int argc, char *argv[]) {
    pthread_t barberid;
    pthread_t clientids[CUSTOMER_NUMBER];
    sem_init(&mutex,0,1);
    sem_init(&barber_ready,0,0);
    sem_init(&cust_ready,0,0);
    pthread_create(&barberid, NULL, barber, NULL);
    for (int i = 0; i < CUSTOMER_NUMBER; i++){
        usleep(interval[i]*1000);
        time_t t = time(NULL);
        struct tm tm = *localtime(&t);
        pthread_create(&clientids[i], NULL, customer, NULL);
        printf("%d:%d:%d: One customer comes, now there are %d seats left now\n", tm.tm_hour, tm.tm_min, tm.tm_sec, seat_num);
    }
}

void *barber(void *param) {
    int worktime = 500;
    while(1) {
        sem_wait(&cust_ready);
        sem_wait(&mutex);
        seat_num += 1;
        time_t t = time(NULL);
        struct tm tm = *localtime(&t);
        printf("%d:%d:%d: Barber works, there are %d seats left now\n", tm.tm_hour, tm.tm_min, tm.tm_sec, seat_num);
        usleep(worktime*1000);
        t = time(NULL);
        tm = *localtime(&t);
        printf("%d:%d:%d: Barber has cut hair, there are %d seats left now\n", tm.tm_hour, tm.tm_min, tm.tm_sec, seat_num);
        sem_post(&barber_ready);
        sem_post(&mutex);
    }
}

void *customer(void *param) {
    sem_wait(&mutex);
    if(seat_num > 0){
        seat_num --;
        time_t t = time(NULL);
        struct tm tm = *localtime(&t);
        printf("%d:%d:%d: One customer comes, now there are %d seats left now\n", tm.tm_hour, tm.tm_min, tm.tm_sec, seat_num);
        sem_post(&cust_ready);
        sem_post(&mutex);
        sem_wait(&barber_ready);
        t = time(NULL);
        tm = *localtime(&t);
        printf("%d:%d:%d: One customer leaves with haircut, now there are %d seats left now\n", tm.tm_hour, tm.tm_min, tm.tm_sec, seat_num);
    } else {
        time_t t = time(NULL);
        struct tm tm = *localtime(&t);
        printf("%d:%d:%d: One customer leaves with no haircut\n", tm.tm_hour, tm.tm_min, tm.tm_sec);
        sem_post(&mutex);
    }
}

原文地址:https://www.cnblogs.com/justsong/p/12219769.html

时间: 2024-10-17 11:54:24

IPC 经典问题:Sleeping Barber Problem的相关文章

IPC 经典问题:Reader &amp; Writer Problem

完整代码实现: #include <stdio.h> #include <unistd.h> #include <time.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define TOTAL_NUMBER 20 void *writer(void *param); void *reader(void *param); int reader_n

操作系统:进程间的相互作用(多线程基础)

进程间的相互作用 两种相互作用 同步 多个相关进程在执行次序上的协调. 制约关系:直接制约. 如图所示:一个进程在执行操作的时候,另一个进程必须等待,体现在次序上的等待和协调,并不争夺临界资源. 互斥 多个进程因为争夺临界资源二相互排斥执行的过程称为进程的互斥. 临界资源:也称为独占资源,是指在一段时间内只允许一个进程访问的资源. 制约关系:间接制约. 解决并发进程的问题 一.加锁法--自旋锁 思路: 设置一个共享变量W (锁) ,初值为0.当一个进程想进入其临界区(进程中涉及临界资源的程序段)

一次完整的从webshell到域控的探索之路

前言 内网渗透测试资料基本上都是很多大牛的文章告诉我们思路如何,但是对于我等小菜一直是云里雾里. 于是使用什么样的工具才内网才能畅通无阻,成了大家一直以来的渴求. 今天小菜我本着所有师傅们无私分享的精神,特将三年内求师傅,求妹子,求神器所得,经过整理后,关键的知识点写出来. 相关知识点总结如下: 免杀 payload 的生成,请使用 Veil msf 在 meterpreter 下的提权尝试 msf 在 meterpreter 下的 bypassuac 尝试 内网渗透测试过程中的信息关联 met

对计算机领域中间层的理解

以前看<代码大全2>时看到了如下一句经典台词: "any problem in computer science can be sloved by another layer of indirecition" "计算机科学领域的任何问题都可以通过增加一个中间层来解决" 当时只是觉得好就永远记住了,几年的编码经验,越来越感受到这句话的经典所在,下面来举几个例子说一下我对它的理解: 1.操作系统的缓存: 比较典型的用于阐述这句话的缓存实例,当属内存(包括sw

[NOI题库]1.3编程基础之算术表达式与顺序执行 题解(一)

01 A+B问题 经典的A+B Problem——各大题库上的首题.读入$a,b$,输出$a+b$. #include <iostream> using namespace std; int main() { int a,b; cin>>a>>b; cout<<a+b<<endl; return 0; } 01.cpp 02 计算(a+b)*c的值 读入$a,b,c$,输出$c(a+b)$. #include <iostream> u

操作系统之进程篇(4)--经典进程间通信(IPC)问题

1. 哲学家进餐问题: 问题描述: 五个哲学家在一个圆桌上进餐,每人的面前放了一盘意大利面,两个盘子之间有一个叉子,但是由于盘子里面的面条十分光滑,需要两个叉子才能进行就餐行为.餐桌的布局如下图所示: 假设哲学家的生活中只有两个活动:吃饭和思考[吃饭维持自身之生存,思考探究生存之意义],当然这样的哲学家在现实之中是不存在的.当一个哲学家在殚精竭虑之时,饥饿感随之而来,这是他会拿起左右手边的两个叉子来想享用这俗世之中的美味.酒足饭饱之后,又"躲进小楼成一统,管他春夏与秋冬"去了.问题是:

HDU 1016 Prime Ring Problem --- 经典DFS

思路:第一个数填1,以后每个数判断该数和前一个数想加是否为素数,是则填,然后标记,近一步递归求解. 然后记得回溯,继续判断下一个和前一个数之和为素数的数. /* HDU 1016 Prime Ring Problem --- 经典DFS */ #include <cstdio> #include <cstring> int n; bool primer[45], visit[25]; //primer打素数表,visit标记是否访问 int a[25]; //数组a存储放置的数 /

白帽Hacker之路:(二)经典中的经典之ipc$入侵——建立IPC$漏洞

(一)什么是IPC$入侵? IPC$入侵,即通过使用Windows 系统中默认启动的IPC$共享,来达到侵略主机,获得计算机控制权的入侵.此类入侵主要利用的是计算机使用者对计算机安全的知识缺乏,通常不会给计算机设置密码或者密码过于简单,因此才导致被黑客的有机可乘. (二)如何查看IPC$共享? 第一步:右键 计算机->管理 第二步:共享文件夹->共享->右侧 即可查看共享的文件夹 (三)如何创建IPC$漏洞? 第一步:win+r   输入gpedit.msc,点击确定,打开本地组策略编辑

Linux 进程间通信(一)(经典IPC:消息队列、信号量、共享存储)

有3种称作XSI IPC的IPC:消息队列.信号量.共享存储.这种类型的IPC有如下共同的特性. 每个内核中的IPC都用一个非负整数标志.标识符是IPC对象的内部名称,为了使多个合作进程能够在同一IPC对象上汇聚,需要提供一个外部命名方案.因此,将每个IPC对象都与一个键相关联,将这个键(key)作为该对象的外部名.这个键的数据类型是key_t,通常在头文件<sys/types.h>中被定义为长整型,该键由内核变换成标识符. 有3种方式可以使客户进程和服务器进程在同一IPC结构上汇聚: (1)