wordpress建两个网站,logo图标素材网站,企业网站建设的要素有哪些,百度投放广告顾得泉#xff1a;个人主页
个人专栏#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》
键盘敲烂#xff0c;年薪百万#xff01; 一、问题描述 #xff08;1#xff09;图书馆阅览室最多能够容纳N#xff08;N5#xff09;名学生#xff0c;若有更多学生想…
顾得泉个人主页
个人专栏《Linux操作系统》 《C/C》 《LeedCode刷题》
键盘敲烂年薪百万 一、问题描述 1图书馆阅览室最多能够容纳NN5名学生若有更多学生想进入阅览室必须等到阅览室中有同学退出之后才能进入。 2阅览室有一名管理员。早到的同学必须等管理员开门之后才能进入管理员必须等到所有同学都退出之后才能关门。 请你用信号量实现上述问题。 二、问题分析 1将在“阅览室读书”看做一个临界区该临界区最多只允许N名学生进入。把每个“学生”建模为一个线程这是一个互斥问题。于是可以设计一个初值为N的信号量实现互斥。 2管理员需要与第一个学生同步即第一个学生等待管理员开门管理员也需要与最后一名学生同步即管理员等待最后一名学生退出之后才能关闭图书馆。因此可以实现一个学生计数实现条件同步。 三、命名规则 1用Student和Manager分别表示学生和管理员线程名。 2Student包括三个操作Checkin( )刷入、Reading( )阅读、checkout( )刷出 3Manager包括三个操作OpenDoor( )开门、CloseDoor( )关门、manage( )
四、具体实现
1. test.c文件 test.c文件是一个模拟学生进出教室的多线程程序。它使用了信号量semaphore来实现同步和互斥。
首先定义了一些全局变量
ns 表示当前正在教室的学生数量。mutex 用于保护对 ns 的访问。room 用于限制教室的最大容量。wfm 和 wfs 分别表示等待进入教室和等待离开教室的信号量。fetch 表示等待学生进入教室的信号量。flag 表示是否已经有学生进入教室。
接下来定义了两个函数
student(void* i) 是每个学生的线程函数。它接收一个参数 i表示学生的编号。manager(void *arg) 是管理线程的函数。它不需要参数。 在 student 函数中首先打印出学生进入教室的信息。然后通过调用 P(fetch) 来请求获取 fetch 信号量表示有学生准备进入教室。接着通过调用 P(mutex) 来请求获取 mutex 信号量以保护对 ns 的访问。然后根据当前的学生数量和是否有学生已经进入教室执行相应的操作。最后释放 mutex 信号量并通过调用 sleep(1) 让当前线程暂停一段时间模拟学生进入教室的过程。然后打印出学生离开教室的信息并释放其他信号量和变量。 在 manager 函数中首先打印出管理打开教室的信息。然后通过调用 V(wfm) 来释放 wfm 信号量表示有学生可以进入教室。接着打印出管理等待所有学生离开教室的信息。然后通过调用 P(wfs) 来请求获取 wfs 信号量表示所有学生都已经离开教室。最后打印出管理关闭教室的信息。 在 main 函数中首先初始化了所有的信号量。然后创建了多个学生线程每个线程对应一个学生编号。接着创建了一个管理线程。最后使用 pthread_exit(NULL) 退出主线程。
#includesemaphore.h
#includepthread.h
#includestdio.h
#includestdlib.h
#includech4-PV.h#define N 5unsigned int ns 0;
sem_t mutex;
sem_t room;
sem_t wfm;
sem_t wfs;
sem_t fetch;
int flag 0;void *student(void* i)
{int id (int)i;printf(Student %i is entring...\n,id);P(fetch);ns;P(mutex);if(ns 1 flag 0){P(wfm);P(room);flag 1;printf(The 1st student %i has been entered.\n,id);}else{P(room);printf(The student %i has been entered\n,id);}V(mutex);sleep(1);printf(The student %i is going to leave...\n,id);P(mutex);ns--;if(ns 0){V(wfs);printf(The last student left.\n);}elseprintf(The student %i has left.\n,id);V(room);V(mutex);V(fetch);
}void *manager(void *arg)
{printf(The manager opens the door.\n);V(wfm);printf(The manager is waiting for all student leaves.\n);P(wfs);printf(The manager closes the door.\n);
}int main()
{sem_init(wfm,0,0);sem_init(fetch,0,5);sem_init(wfs,0,0);sem_init(mutex,0,1);sem_init(room,0,5);pthread_t tid;for(int i 1; i N; i)pthread_create(tid,NULL,student,(void *)i);pthread_create(tid,NULL,manager,(void *)NULL);pthread_exit(NULL);return 0;
}2. ch4-PV.c文件 这段代码是一个简单的信号量实现用于实现生产者消费者问题。其中包含了两个函数P() 和 V()。
P(sem_t *s) 函数用于等待信号量。如果信号量的值大于0则将信号量的值减1并返回否则该函数会阻塞直到信号量的值变为大于0。V(sem_t *s) 函数用于释放信号量。将信号量的值加1并唤醒一个等待该信号量的线程。
#includestdio.h
#includesemaphore.h
#includestdlib.h
#includech4-PV.hvoid P(sem_t *s)
{if(sem_wait(s)0)printf(P error);
}void V(sem_t *s)
{if(sem_post(s)0)printf(V error);
}3. ch4-PV.h文件 这段代码定义了相应的头文件。
#includesemaphore.h
#includeunistd.hvoid P(sem_t *s);
void V(sem_t *s);
4. makeflie文件 这是一个Makefile文件用于编译和清理生成的可执行文件和目标文件。之前的文章对此有过相应的讲解
test:test.o ch4-PV.ogcc -pthread test.o ch4-PV.o -o test
tets.o:test.cgcc -c test.c
ch4-PV.o:ch4-PV.cgcc -c ch4-PV.c
.PHONY:cleanclean:rm -rf ch4-PV.orm -rf testrm -rf test.o
五、实现结果
首先进行make操作 进行查看是否编译 运行文件 进行make clean操作 到此一个简单的图书馆同步问题就实现了。 结语Linux系统关于图书管理同步问题的分享到这里就结束了希望本篇文章的分享会对大家的学习带来些许帮助如果大家有什么问题欢迎大家在评论区留言~~~