实现简单的PV操作
#include <stdio.h>
#include <stdlib.h>
struct process {
int pid;
struct process* next;
};
typedef struct {
int value;
struct process* list;
}semaphore;
void print_blocklist(semaphore* s)
{
struct process* p=s->list;
if (p == NULL)
{
printf("阻塞队列为空\n");
}
else
{
printf("阻塞队列为:>");
while (p != NULL)
{
printf("%d ->", p->pid);
p = p->next;
}
printf("NULL\n");
}
}
void block(struct process** list, struct process p) {
if (*list == NULL)
{
*list = (struct process*)malloc(sizeof(struct process));
(*list)->pid = p.pid;
(*list)->next = NULL;
}
else
{
struct process* d = *list;
while (d->next != NULL)
{
d = d->next;
}
struct process* q = (struct process*)malloc(sizeof(struct process));
q->pid = p.pid;
q->next = NULL;
d->next = q;
}
}
void wakeup(struct process** list)
{
if (*list != NULL)
{
struct process *d = *list;
struct process p = *d;
*list = (*list)->next;
free(d);
printf("第%d号进程已经被唤醒\n", p.pid);
}
}
void wait(semaphore* S,struct process p)
{
printf("第%d号进程正在尝试申请资源\n",p.pid);
S->value--;
if (S->value < 0)
{
printf("第%d号进程申请资源失败,进程已经被阻塞\n",p.pid);
block(&(S->list), p);
}
else
{
printf("第%d号进程申请资源成功\n", p.pid);
}
if (S->value < 0)
{
print_blocklist(S);
}
}
void signal(semaphore* S,struct process p)
{
printf("第%d号进程正在尝试释放资源\n",p.pid);
S->value++;
if (S->value <= 0)
{
printf("第%d号进程成功释放资源,已经唤醒新的阻塞进程\n",p.pid);
wakeup(&(S->list));
}
else
{
printf("第%d号进程成功释放资源,阻塞队列没有新的进程\n", p.pid);
}
}
int main()
{
semaphore mutex;
mutex.value = 2;
mutex.list = NULL;
struct process p1, p2, p3, p4;
p1.pid = 1;
p2.pid = 2;
p3.pid = 3;
p4.pid = 4;
wait(&mutex, p1);
wait(&mutex, p2);
wait(&mutex, p3);
signal(&mutex, p1);
wait(&mutex, p4);
signal(&mutex, p2);
signal(&mutex, p3);
signal(&mutex, p4);
return 0;
}
只能实现简单的PV操作,并不能还原真正的进程间通信,另外一定要记得在main函数中初始化semaphore的list,否则block函数会报错(找了一晚上的错才找出来的。。。)。
利用多线程编程实现简单的吸烟者问题
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
sem_t offer1;
sem_t offer2;
sem_t offer3;
sem_t finish;
int i;
void* supplier_process(void* arg)
{
printf("供应商到来,开始提供物品\n");
while (1)
{
srand((unsigned)time(NULL));
i = rand() % 3;
if (i == 0)
{
printf("供应商提供胶水和纸\n");
Sleep(2000);
sem_post(&offer1);
}
else if (i == 1)
{
printf("供应商提供烟草和胶水\n");
Sleep(2000);
sem_post(&offer2);
}
else
{
printf("供应商提供纸和烟草\n");
Sleep(2000);
sem_post(&offer3);
}
printf("供应商等待吸烟完成\n");
sem_wait(&finish);
}
}
void* smoker_process_one(void* arg)
{
printf("第一位吸烟者到来,要吸烟\n");
while (1)
{
sem_wait(&offer1);
printf("第一个吸烟者拥有烟草,拿着供应商给的纸和胶水,卷烟吸烟\n");
Sleep(10000);
printf("第一个吸烟者吸烟完成\n");
sem_post(&finish);
}
}
void* smoker_process_two(void* arg)
{
printf("第二位吸烟者到来,要吸烟\n");
while (1)
{
sem_wait(&offer2);
printf("第二个吸烟者拥有纸张,拿着供应商给的烟草和胶水,卷烟吸烟\n");
Sleep(10000);
printf("第二个吸烟者吸烟完成\n");
sem_post(&finish);
}
}
void* smoker_process_three(void* arg)
{
printf("第三位吸烟者到来,要吸烟\n");
while (1)
{
sem_wait(&offer3);
printf("第三个吸烟者拥有胶水,拿着供应商给的纸和烟草,卷烟吸烟\n");
Sleep(10000);
printf("第三个吸烟者吸烟完成\n");
sem_post(&finish);
}
}
int main()
{
sem_init(&offer1, 0, 0);
sem_init(&offer2, 0, 0);
sem_init(&offer3, 0, 0);
sem_init(&finish, 0, 0);
pthread_t supple;
pthread_t smoker[3];
pthread_create(&supple, nullptr, supplier_process, nullptr);
pthread_create(&smoker[0], nullptr, smoker_process_one, nullptr);
pthread_create(&smoker[1], nullptr, smoker_process_two, nullptr);
pthread_create(&smoker[2], nullptr, smoker_process_three, nullptr);
pthread_join(supple, nullptr);
pthread_join(smoker[0], nullptr);
pthread_join(smoker[1], nullptr);
pthread_join(smoker[2], nullptr);
return 0;
}
实现效果图