操作系统课程设计文档格式.docx
《操作系统课程设计文档格式.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
![操作系统课程设计文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/2/3e5f1575-7aa8-44b0-ad0b-4dfe61432510/3e5f1575-7aa8-44b0-ad0b-4dfe614325101.gif)
进程id的类型是pid_t,每个进程的id在整个系统中是唯一的,pid_t=getpid
(2),是一个正整数值。
线程id的类型是thread_t,它只在当前进程中保证是唯一的,在不同的系统中thread_t这个类型有不同的实现,它可能是一个整数值,也可能是一个结构体,也可能是一个地址,thread_t=pthread_self(3)。
(2).线程终止(pthread_exit)
voidpthread_exit(void*value_ptr);
value_ptr是void*类型,和线程函数返回值的用法一样,其它线程可以调用pthread_join获得这个指针。
(3).线程等待(pthread_join)
intpthread_join(pthread_tthread,void**value_ptr);
返回值:
2.互斥锁(Mutex)
(1).初始化(mutex_init)
Mutex用pthread_mutex_t类型的变量表示;
intpthread_mutex_init(pthread_mutex_t*restrictmutex,constpthread_mutexattr_t*restrictattr);
pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;
成功返回0,失败返回错误号。
(2).销毁(pthread_mutex_destroy)
intpthread_mutex_destroy(pthread_mutex_t*mutex);
(3).加锁和解锁(mutex_lock、mutex_trylock、mutex_unlock)
intpthread_mutex_lock(pthread_mutex_t*mutex);
intpthread_mutex_trylock(pthread_mutex_t*mutex);
intpthread_mutex_unlock(pthread_mutex_t*mutex);
一个线程可以调用pthread_mutex_lock获得Mutex,如果这时另一个线程已经调用pthread_mutex_lock获得了该Mutex,则当前线程需要挂起等待,直到另一个线程调用pthread_mutex_unlock释放Mutex,当前线程被唤醒,才能获得该Mutex并继续执行。
3.条件变量(ConditionVariable)
(1).在pthread库中通过条件变量(ConditionVariable)来阻塞等待一个条件,或者唤醒等待这个条件的线程。
ConditionVariable用pthread_cond_t类型的变量表示。
(2).初始化和销毁(pthread_cond_init、pthread_cond_destroy)
intpthread_cond_destroy(pthread_cond_t*cond);
intpthread_cond_init(pthread_cond_t*restrictcond,
constpthread_condattr_t*restrictattr);
pthread_cond_tcond=PTHREAD_COND_INITIALIZER;
Mutex的初始化和销毁类似,pthread_cond_init函数初始化一个条件变量,attr参数为NULL则表示缺省属性,pthread_cond_destroy函数销毁一个ConditionVariable。
如果条件变量是静态分配的,也可以用宏定义PTHEAD_COND_INITIALIZER初始化,相当于用pthread_cond_init函数初始化并且attr参数为NULL。
(3).条件的触发(pthread_cond_timedwait)、广播(pthread_cond_broadcast)、等待(pthread_cond_wait)
intpthread_cond_timedwait(pthread_cond_t*restrictcond,
pthread_mutex_t*restrictmutex,conststructtimespec
*restrictabstime);
intpthread_cond_wait(pthread_cond_t*restrictcond,pthread_
mutex_t*restrictmutex);
intpthread_cond_broadcast(pthread_cond_t*cond);
intpthread_cond_signal(pthread_cond_t*cond);
4、设计
概要:
通过三组共九个信号量解决线程间的协作和互斥问题。
设计思路:
1通过三组信号量解决互斥问题。
每组信号量控制一个缓存空间。
2.设计一个判断,用于区分不同组的生产者和消费者。
3.设计一个消费平衡机制,尽量平衡消费者的消费意向。
平衡生产者的缓存空间。
4.设计一个判断,用于判定消费者应当退出。
重要代码注释:
1.信号量定义
sem_tempty_sem0;
//同步信号量,当满了时阻止生产者放产品第一组
sem_tfull_sem0;
//同步信号量,当没产品时阻止消费者消费第一组
pthread_mutex_tmutex0;
//互斥信号量一次只有一个线程访问缓冲第一组
sem_tempty_sem1;
//同步信号量,当满了时阻止生产者放产品第二组
sem_tfull_sem1;
//同步信号量,当没产品时阻止消费者消费第二组
pthread_mutex_tmutex1;
//互斥信号量,一次只有一个线程访问缓冲第二组
sem_tempty_sem2;
//同步信号量,当满了时阻止生产者放产品第三组
sem_tfull_sem2;
//同步信号量,当没产品时阻止消费者消费第三组
pthread_mutex_tmutex2;
//互斥信号量,一次只有一个线程访问缓冲第三组
2.
sem_wait(&
empty_sem2);
//生产者核心代码
pthread_mutex_lock(&
mutex2);
in=in%M;
printf("
(P2)product%din%d\n"
id,in);
buff[2][in]=1;
++in;
pthread_mutex_unlock(&
sem_post(&
full_sem2);
3.//消费者核心代码
sem_wait(&
full_sem0);
pthread_mutex_lock(&
mutex0);
out=out%M;
printf("
(C0)prochase%din%d\n"
id,out);
buff[0][out]=0;
++out;
pthread_mutex_unlock(&
sem_post(&
empty_sem0);
5、测试
运行结果分析:
6、总结
信号量可以有效的解决互斥问题,在编程过程中需要注意信号量修改的顺序。
程序关于不同生产者处理的细节较易出错。
事实上也是如此,调试阶段对细节进行了大量的修改和优化。
程序调试阶段,多线程的处理上出现较多出错误。
说明我在线程处理的细节上还有待加强。
本程序在10~30号生产者产品的处理上有些仓促。
只是用了一个简单的平衡处理,实际效果一般。
目前未发现不良后果。
有待后续改进。
7、源代码
stdio.h>
stdlib.h>
unistd.h>
semaphore.h>
#include<
sys/types.h>
sys/sem.h>
sys/mman.h>
sys/ipc.h>
#defineN30//消费者或者生产者的数目
#defineM20//缓冲数目
#defineD30//生产者生产产品上限
intPn[3]={0};
//活动中的生产者
intin=0;
//生产者放置产品的位置
intout=0;
//消费者取产品的位置
intbuff[3][M]={0};
//缓冲初始化为0,开始时没有产品
//同步信号量,当满了时阻止生产者放产品第二组
intproduct_id=0;
//生产者id
intprochase_id=0;
//消费者id
/*生产者方法*/
void*product()
{
intid=++product_id;
if(id>
10)
{
Pn[2]++;
//生产者+1
inti=D;
//产品计数
while(i--)
{
//用sleep的数量可以调节生产和消费的速度,便于观察
sleep
(1);
}
Pn[2]--;
//生产者完成上限,-1
}
else
if(id%2==0)
Pn[0]++;
inti=D;
while(i--)
{
//用sleep的数量可以调节生产和消费的速度,便于观察
sleep
(1);
in=in%M;
(P0)product%din%d\n"
buff[0][in]=1;
++in;
}
Pn[0]--;
else
{
Pn[1]++;
empty_sem1);
mutex1);
(P1)product%din%d\n"
buff[1][in]=1;
full_sem1);
Pn[1]--;
}
}
}
/*消费者方法*/
void*prochase()
intid=++prochase_id;
if(id%2==0)
inti=1,m=-1,n=-1;
//消费者消费意向平衡
while
(1)
if(i>
0)
{i=m*i;
//消费意向转移
//sleep
(1);
if(Pn[0]==0)n=1;
//此消费意向作废
else
{i=n*i;
(C1)prochase%din%d\n"
buff[2][out]=0;
//print
(1);
if(Pn[2]==0)m=1;
if(m==1&
&
n==1)break;
inti=1,m=-1,n=-1;
if(i>
{
i=m*i;
buff[1][out]=0;
if(Pn[1]==0)n=1;
{i=n*i;
if(Pn[2]==0)
m=1;
intmain()
pthread_tid1[N];
pthread_tid2[N];
inti;
intret[N];
//初始化同步信号量
intini1=sem_init(&
empty_sem0,0,M);
intini2=sem_init(&
full_sem0,0,0);
intini3=sem_init(&
empty_sem1,0,M);
intini4=sem_init(&
full_sem1,0,0);
intini5=sem_init(&
empty_sem2,0,M);
intini6=sem_init(&
full_sem2,0,0);
if(ini1&
ini2&
ini3&
ini4&
ini5&
ini6!
=0)
printf("
seminitfailed\n"
);
exit
(1);
//初始化互斥信号量
intini7=pthread_mutex_init(&
mutex0,NULL);
intini8=pthread_mutex_init(&
mutex1,NULL);
intini9=pthread_mutex_init(&
mutex2,NULL);
if(ini7&
ini8&
ini9!
mutexinitfailed\n"
//创建N个生产者线程
for(i=0;
i<
N;
i++)
ret[i]=pthread_create(&
id1[i],NULL,product,(void*)(&
i));
if(ret[i]!
product%dcreationfailed\n"
i);
exit
(1);
//创建N个消费者线程
id2[i],NULL,prochase,(void*)(&
i));
prochase%dcreationfailed\n"
//销毁线程
pthread_join(id1[i],NULL);
pthread_join(id2[i],NULL);
exit(0);