#include<stdio.h>
#include<stdlib.h>
#define READY 1
#define RUN 2
#define BLOCK 3
typedef struct pcbNode
{
int num
struct pcbNode *next
int cputime
int state
}pcb
pcb *head
pcb *run
pcb *CreatPCB(int n)
{
int i
pcb *p,*q
head=(pcb *)malloc(sizeof(pcb))
head->next=NULL
p=head
for(i=1i<=ni++)
{
q=(pcb *)malloc(sizeof(pcb))
q->num=i
q->next=NULL
q->cputime=rand()%100
q->state=READY
p->next=q
p=q
}
return head
}
void DeletePCB()
{
pcb *p
if(head->next!=NULL)
{
p=head->next
head->next=head->next->next
free(p)
}
}
void Display()
{
pcb *p
p=head->next
while(p)
{
printf(" %d",p->num)
p=p->next
}
printf("\n")
}
void control()
{
run=head->next
run->state=RUN
{ while(run->cputime)
run->cputime--
printf("正在执行的进程编号为: %d\n",run->num)
run->state=RUN
run=run->next
DeletePCB()
printf("执行进程后就绪队列中的进程:")
Display()
printf("\n")
}
}
void main(void)
{
int n
int flag=1
printf("请输入要创建的进程的数量:")
scanf("%d",&n)
head=CreatPCB(n)
printf("就绪队列里的进程有:")
Display()
printf("\n")
while(flag)/*由flag的值判断是否继续执行control()函数*/
{
if(head->next)/*判断进程是否完成*/
control()
else flag=0
}
printf("\n")
}
#include <conio.h>#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <string.h>
struct PCB_type
{ char pid[100] //进程名输入用字符串健壮性比较好
int priority
int cputime
int state
} //缺少“}”
int shumu=0,pid_l
struct PCB_type neicun[20]
struct PCB_type hc[10]
int max=0
int number=0
void create()
void run()
void huanchu()
void kill()
int main()
{
int n,a
n=1
system("color 1d")
while(n==1)
{
system("cls")
printf("\n**********************************************")
printf("\n* 进程演示系统 *")
printf("\n**********************************************")
printf("\n 1.创建新的进程 2.查看运行进程")
printf("\n 3.换出某个进程 4.杀死运行进程") //新增了一个唤醒功能
printf("\n 5.退出系统 ")
printf("\n**********************************************")
printf("\n请选择(1~5):")
scanf("%d",&a)
switch(a)
{ case 1:
create( )
printf("\npress any key to go on~")
getch()
break
case 2 :
run()
printf("\npress any key to go on~")
getch()
break
case 3 :
huanchu()
printf("\npress any key to go on~")
getch()
break
case 4 :
kill()
printf("\npress any key to go on~")
getch()
break
case 5 :
exit(0)
default:
n=1
break
}
}
}
void create()
{
if(shumu>=20)
{
printf("\n内存已满,请先结束或换出进程\n")
}
else
{
shumu++
printf("\n请输入新进程的程序名\n")
scanf("%s",neicun[shumu-1].pid)
printf("\n请输入新进程的优先级(数字)\n")//
scanf("%d",&neicun[shumu-1].priority)
printf("\n请输入新进程的需要的运行时间\n")//
scanf("%d",&neicun[shumu-1].cputime)
printf("\n创建进程时令其状态为就绪\n")
neicun[shumu-1].state=2 //1为等待,2就绪,3为运行
}
printf("\n创建进程成功!\n")
}
void run()
{
if(shumu<=0)//查看//判断是否存在进程
{
printf("当前状态无进程,按任意键继续创建进程\n")
return
}
int max=0
for(int i=0i<shumui++)//
if((neicun[i].state==2&&neicun[i].priority>=neicun[max].priority))
{
max=i //这里判断优先级,优先级高的进程优先执行。
}
if(neicun[max].state==2)
{
neicun[max].state=3 //进程运行,状态为3
system("color 5F")
printf("/*********************当前已有进程%d个*************************/:\n",shumu)
for(int i=0i<shumui++){
printf("进程编号:%d",i+1)
printf("\n/***********正在运行进程程序名:%s*************************/\n",neicun[i].pid)
printf("\n/***********该进程的优先级:%d*****************************/\n",neicun[i].priority)
printf("\n/***********该进程的需要运行时间:%d***********************/\n",neicun[i].cputime)
printf("\n/***********该进程的状态:%d(1为等待,2就绪,3为运行)******/\n\n\n",neicun[i].state) } //这里增加显示当前运行的进程
}
}
/* 换出 */
void huanchu()
{
int k
if(shumu<=0)//判断是否存在进程
{
printf("当前进程数目为0,不能执行该 *** 作\n")
return
}
printf("当前已有进程%d个:\n",shumu)
for(int h=0h<shumuh++)//当前所有的进程
printf("序号:%d\t程序名:%s\t优先级:%d\t运行时间:%d\t状态:%d\t\n"
,h,neicun[h].pid,neicun[h].priority,neicun[h].cputime,neicun[h].state)
printf("请输入要换出程序的序号:")
scanf("%d",&k)
if(neicun[k].state==3)
{
neicun[k].state=1
printf("已被换出,进程名为:%s、状态为:[%d]",neicun[k].pid,neicun[k].state)
}
else
printf("无法换出,进程名为:%s的进程",neicun[k].pid) //换出结果提示
}
void kill()
{
if(shumu<=0)//对存在的进程进行判断
{
printf("当前进程数目为0,不能执行该 *** 作\n")
return
}
int k=0
printf("/******************当前已有进程%d个******************/:\n",shumu)
for(int h=0h<shumuh++)//当前所有的进程
printf("序号:%d\t程序名:%s\t优先级:%d\t运行时间:%d\t状态:%d\t\n"
,h,neicun[h].pid,neicun[h].priority,neicun[h].cputime,neicun[h].state)
printf("请输入要杀死程序的序号:")
scanf("%d",&k)
neicun[k].cputime=0
neicun[k].priority=0
neicun[k].state=0
if(k==(shumu-1))
shumu--
else{
for(int j=k+1j<shumuj++)
{
strcmp(neicun[j-1].pid,neicun[j].pid)
neicun[j-1].priority=neicun[j].priority
neicun[j-1].cputime=neicun[j].cputime
neicun[j-1].state=neicun[j].state
}
shumu--
}
printf("进程名为:%s已被杀死!\n",neicun[k].pid) //显示进程已被杀死
}
这个问题需要的知识主要包括:
1 多进程间进行通信;
2 使用同步信号量(semaphore)和互斥信号量(mutex)进行数据保护。
参考代码如下,可以参照注释辅助理解:
#include <stdio.h>#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define N 2 // 消费者或者生产者的数目
#define M 10 // 缓冲数目
int in = 0 // 生产者放置产品的位置
int out = 0 // 消费者取产品的位置
int buff[M] = {0} // 缓冲初始化为0, 开始时没有产品
sem_t empty_sem // 同步信号量, 当满了时阻止生产者放产品
sem_t full_sem // 同步信号量, 当没产品时阻止消费者消费
pthread_mutex_t mutex // 互斥信号量, 一次只有一个线程访问缓冲
int product_id = 0 //生产者id
int prochase_id = 0 //消费者id
/* 打印缓冲情况 */
void print()
{
int i
for(i = 0 i < M i++)
printf("%d ", buff[i])
printf("\n")
}
/* 生产者方法 */
void *product()
{
int id = ++product_id
while(1)
{
// 用sleep的数量可以调节生产和消费的速度,便于观察
sleep(1)
//sleep(1)
sem_wait(&empty_sem)
pthread_mutex_lock(&mutex)
in = in % M
printf("product%d in %d. like: \t", id, in)
buff[in] = 1
print()
++in
pthread_mutex_unlock(&mutex)
sem_post(&full_sem)
}
}
/* 消费者方法 */
void *prochase()
{
int id = ++prochase_id
while(1)
{
// 用sleep的数量可以调节生产和消费的速度,便于观察
sleep(1)
//sleep(1)
sem_wait(&full_sem)
pthread_mutex_lock(&mutex)
out = out % M
printf("prochase%d in %d. like: \t", id, out)
buff[out] = 0
print()
++out
pthread_mutex_unlock(&mutex)
sem_post(&empty_sem)
}
}
int main()
{
pthread_t id1[N]
pthread_t id2[N]
int i
int ret[N]
// 初始化同步信号量
int ini1 = sem_init(&empty_sem, 0, M)
int ini2 = sem_init(&full_sem, 0, 0)
if(ini1 && ini2 != 0)
{
printf("sem init failed \n")
exit(1)
}
//初始化互斥信号量
int ini3 = pthread_mutex_init(&mutex, NULL)
if(ini3 != 0)
{
printf("mutex init failed \n")
exit(1)
}
// 创建N个生产者线程
for(i = 0 i < N i++)
{
ret[i] = pthread_create(&id1[i], NULL, product, (void *)(&i))
if(ret[i] != 0)
{
printf("product%d creation failed \n", i)
exit(1)
}
}
//创建N个消费者线程
for(i = 0 i < N i++)
{
ret[i] = pthread_create(&id2[i], NULL, prochase, NULL)
if(ret[i] != 0)
{
printf("prochase%d creation failed \n", i)
exit(1)
}
}
//销毁线程
for(i = 0 i < N i++)
{
pthread_join(id1[i],NULL)
pthread_join(id2[i],NULL)
}
exit(0)
}
在Linux下编译的时候,要在编译命令中加入选项-lpthread以包含多线程支持。比如存储的C文件为demo.c,要生成的可执行文件为demo。可以使用命令:
gcc demo.c -o demo -lpthread
程序中为便于观察,使用了sleep(1)来暂停运行,所以查看输出的时候可以看到,输出是每秒打印一次的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)