线程实现邮箱通信实验报告Word文件下载.docx
- 文档编号:17280207
- 上传时间:2022-11-30
- 格式:DOCX
- 页数:12
- 大小:29.79KB
线程实现邮箱通信实验报告Word文件下载.docx
《线程实现邮箱通信实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《线程实现邮箱通信实验报告Word文件下载.docx(12页珍藏版)》请在冰豆网上搜索。
sem_op:
如果其值为正数,该值会加到现有的信号内含值中。
通常用于释放所控资源的使用权;
如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。
通常用于获取资源的使用权;
如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。
sem_flg:
信号操作标志,可能的选择有两种
IPC_NOWAIT//对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。
IPC_UNDO//程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。
这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。
2、semop函数
函数原型:
intsemop(intsemid,structsembuf*sops,unsignednsops);
参数说明:
semid:
信号集的识别码,可通过semget获取。
sops:
指向存储信号操作结构的数组指针。
nsops:
信号操作结构的数量,恒大于或等于1。
返回说明:
成功执行时,两个系统调用都返回0。
失败返回-1,错误信息保存在errno中。
3、semget函数
intsemget(key_tkey,intnsems,intsemflg);
key:
关键字值一般是由系统调用ftok()返回的
nsems:
指出了一个新的信号量集中应该创建的信号量的个数
semflg:
打开和存取操作与参数semflg中的内容相关。
如果成功,则返回信号量集的IPC标识符。
如果失败,返回-1,错误信息保存在errno中。
4、semctl函数
intsemctl(intsemid,intsemnum,intcmd,unionsemunarg);
senid:
关键字值
semnum:
信号量数目
cmd:
要操作的具体命令
arg:
semnu的一个联合类型的副本。
返回值:
如果成功,则为一个正数。
如果失败,则为-1。
错误信息保存在errno中。
5、pthread_create函数
intpthread_create(pthread_t*restricttidp,constpthread_attr_t*restrictattr,void*(*start_rtn)(void*),void*restrictarg);
tidp:
指向线程标识符的指针。
attr:
用来设置线程属性。
第三个参数是线程运行函数的起始地址。
运行函数的参数。
六、设计方案:
1、定义两个数组当作两个邮箱inta_buf[5],b_buf[5];
邮箱的容量为5。
2、定义两个指针指向邮箱的顶部inta_buf_top=0,b_buf_top=0;
初始时邮箱都为空
3、定义semaphore_P和semaphore_V两个函数实现P.V原语操作,用P.V原语实现进程的互斥。
4、定义发送和接收信息的函数,其中void*A_Send(void*arg)为A发送信息,void*B_Send(void*arg)为B发送信息,void*A_Receive(void*arg)为A接收信息;
void*B_Receive(void*arg)为B接收信息。
5、调用创建线程函数,让上述四个函数并行运行。
七、预计的实验结果:
A_Receive()和B_Receive()分别接收B_Send()和A_Send()发出的信息,发送的信息和接受的信息应该一样。
八、关键代码的分析:
/****************************************
*P原语操作
**************************************/
intsemaphore_P(intsem_id)
structsembufp;
p.sem_num=0;
p.sem_op=-1;
p.sem_flg=SEM_UNDO;
if(semop(sem_id,&
p,1)==-1)
{
printf(errno);
return0;
}
return1;
}
/***************************************
*V原语操作
***********************************/
intsemaphore_V(intsem_id)
structsembufv;
v.sem_num=0;
v.sem_op=1;
v.sem_flg=SEM_UNDO;
v,1)==-1)
*A向B发送信息
*************************************/
void*A_Send(void*arg)
inti;
for(i=0;
i<
10;
i++)
semaphore_P(sem_idAs);
//P操作
semaphore_P(a_mutex_semaphore);
//互斥
intnumber=rand();
//随机数为发送的邮件
printf("
AsendtoB:
%d\n"
number);
b_buf[b_buf_top]=number;
//邮箱B中接收A发送的邮件
b_buf_top+=1;
//A向B发送邮件,B的邮件数量加一
semaphore_V(a_mutex_semaphore);
semaphore_V(sem_idBr);
//V操作
sleep
(1);
九、调试记录:
于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时,在编译中要加-lpthread参数
gcc-w-lpthreadsemaphore.c
十、实际的实验结果:
ada@ada-desktop:
~/OS$gcc-w-osemaphore-lpthreadsemaphore.c
~/OS$./semaphore
BsendtoA:
1804289383
AreceivefromB:
846930886
BreceivefromA:
846930886
1681692777
1714636915
1714636915
1957747793
424238335
424238335
719885386
1649760492
1649760492
596516649
1189641421
1189641421
1025202362
1350490027
1350490027
783368690
1102520059
1102520059
2044897763
1967513926
1967513926
1365180540
1540383426
1540383426
304089172
1303455736
1303455736
~/OS$
十一、实验结果分析:
四个线程并发运行,A_Send()和B_Send()发出信息,同时打印出发出的信息内容;
A_Receive()和B_Receive()分别接收B_Send()和A_Send()发出的信息,并打印出接受的信息内容。
发出的内容和接收的内容一样,符合时间情况。
十二、附代码
#include<
unistd.h>
stdlib.h>
stdio.h>
pthread.h>
semaphore.h>
sys/types.h>
sys/ipc.h>
sys/sem.h>
errno.h>
inta_buf[5],b_buf[5];
//邮箱的容量为5
inta_buf_top=0,b_buf_top=0;
//假设初始时邮箱都为空
intsem_idAs,sem_idBs;
//例如sem_idAs代表A此时最多可以向B发送的邮件数
intsem_idAr,sem_idBr;
//例如sem_idAr代表A此时邮箱中受到的邮件数
inta_mutex_semaphore,b_mutex_semaphore;
//互斥信号量
b_buf[*b_top]=num++;
//邮箱B中接收A发送的邮件,
(*b_top)+=1;
*A接收B的信息
****************************************/
void*A_Receive(void*arg)
{
for(i=0;
i++)
semaphore_P(sem_idAr);
//P操作
semaphore_P(b_mutex_semaphore);
//互斥
a_buf_top-=1;
//A接收B发送邮件,A的邮件数量减一
a_buf[a_buf_top]);
semaphore_V(b_mutex_semaphore);
semaphore_V(sem_idBs);
*B向A发送信息
void*B_Send(void*arg)
semaphore_P(sem_idBs);
a_buf[a_buf_top]=number;
a_buf_top+=1;
semaphore_V(sem_idAr);
*B接收A的信息
void*B_Receive(void*arg)
semaphore_P(sem_idBr);
b_buf_top-=1;
%d\n"
b_buf[b_buf_top]);
semaphore_V(sem_idAs);
intmain()
/*创建线程1*/
pthread_tthread1;
pthread_tthread2;
pthread_tthread3;
pthread_tthread4;
/*创建信号量*/
if((sem_idAs=semget((key_t)1,1,IPC_CREAT|0660))==-1)
return1;
if((sem_idBs=semget((key_t)2,1,IPC_CREAT|0660))==-1)
if((sem_idAr=semget((key_t)3,1,IPC_CREAT|0660))==-1)
if((sem_idBr=semget((key_t)4,1,IPC_CREAT|0660))==-1)
if((a_mutex_semaphore=semget((key_t)5,1,IPC_CREAT|0660))==-1)
if((b_mutex_semaphore=semget((key_t)6,1,IPC_CREAT|0660))==-1)
/*控制信号队列的运作*/
semctl(sem_idAs,0,SETVAL,0);
semctl(sem_idBs,0,SETVAL,0);
semctl(sem_idAr,0,SETVAL,0);
semctl(sem_idBr,0,SETVAL,0);
semctl(a_mutex_semaphore,0,SETVAL,1);
semctl(b_mutex_semaphore,0,SETVAL,1);
//调用四个线程,让四个函数并行运行
pthread_create(&
thread1,NULL,A_Send,NULL);
thread2,NULL,B_Send,NULL);
thread3,NULL,A_Receive,NULL);
thread4,NULL,B_Receive,NULL);
sleep(60);
//保证主程序退出之前邮箱操作已经完成
return0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 线程 实现 邮箱 通信 实验 报告