试验线程同步与通信-KeShi课件_第1页
试验线程同步与通信-KeShi课件_第2页
试验线程同步与通信-KeShi课件_第3页
试验线程同步与通信-KeShi课件_第4页
试验线程同步与通信-KeShi课件_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验三(1)、线程同步与通信一、实验目的

1、掌握Linux下线程的概念;

2、了解Linux线程同步与通信的主要机制; 3、通过信号灯操作实现线程间的同步与互斥。实验三(1)、线程同步与通信一、实验目的二、实验内容

通过Linux多线程与信号灯机制,设计并实现计算机线程与I/O线程共享缓冲区的同步与通信。程序要求:两个线程,共享公共变量a

线程1负责计算(1到100的累加,每次加一个数)

线程2负责打印(输出累加的中间结果)二、实验内容三、预备知识1、Linux下的信号灯及其P、V操作 在Linux中信号灯是一个数据集合,可以单独使用这一集合的每个元素。 有关的系统调用命令: 1)semget:返回一个被内核指定的整型的信号灯索引。 2)semop:执行对信号灯集的操作 3)semctl:执行对信号灯集的控制操作。三、预备知识信号灯的定义:

数据结构的原型是semid_ds,在linux/sem.h中定义:

structsemid_ds{

structipc_permsem_perm;/*permissions..seeipc.h*/

time_tsem_otime;/*lastsemoptime*/

time_tsem_ctime;/*lastchangetime*/

structsem*sem_base;/*ptrtofirstsemaphoreinarray*/

structwait_queue*eventn;

structwait_queue*eventz;

structsem_undo*undo;/*undorequestsonthisarray*/

ushortsem_nsems;/*no.ofsemaphoresinarray*/

};

信号灯的定义:信号量的创建:

使用系统调用semget()创建一个新的信号量集,或者存取一个已经存在的信号量集.

原型:intsemget(key_tkey,intnsems,intsemflg);

返回值:如果成功,则返回信号量集的IPC标识符。如果失败,则返回-1.

semflg:IPC_CREAT|0666nsems:信号灯的个数信号量的创建:信号量的操作: 系统调用semop();

调用原型:intsemop(intsemid,structsembuf*sops,unsignednsops);

返回值:0,如果成功。-1,如果失敗

structsembuf{

ushortsem_num;/*semaphoreindexinarray*/

shortsem_op;/*semaphoreoperation*/

shortsem_flg;/*operationflags*/ }

sem_num将要处理的信号量的下标。 sem_op要执行的操作。

sem_flg操作标志,IPC_NOWAIT信号量的操作: 系统调用semop();

调用原型:intP操作voidP(intsemid,intindex){ structsembufsem; sem.sem_num=index;sem.sem_op=-1; sem.sem_flg=0;

//操作标记:0或IPC_NOWAIT等semop(semid,&sem,1); //1:表示执行命令的个数 return;}P操作V操作 voidV(intsemid,intindex) { structsembufsem; sem.sem_num=index;sem.sem_op=1;sem.sem_flg=0; semop(semid,&sem,1); return; }V操作信号量的赋值:系统调用semctl()

原型:intsemctl(intsemid,intsemnum,intcmd,unionsemunarg);

返回值:如果成功,则为一个正数。 参数cmd中可以使用的命令如下: ·IPC_RMID将信号量集从内存中删除。

·SETALL设置信号量集中的所有的信号量的值。

·SETVAL设置信号量集中的一个单独的信号量的值。

arg.val=1; semctl(semid,1,SETVAL,arg)信号量的赋值:系统调用semctl()

原型:intsem2、线程1)线程创建pthread_create(pthread_t*thread,pthread_attr_t *attr, void*(*start_routine)(void*),void*arg);2)pthread_join(pthread_tth,void**thread_retrun);作用:挂起当前线程直到由参数th指定的线程被终止为止。2、线程3、编辑、编译、调试

$vi $cc–otest-gtest.c–lpthread

$gdb3、编辑、编译、调试四、实验指导程序结构

#include头文件pthread.h、sys/types.h、linux/sem.h等 P、V操作的函数定义:

voidP(intsemid,intindex)

voidV(intsemid,intindex) 信号灯、线程句柄定义:

intsemid; pthread_tp1,p2; 线程执行函数定义:void*subp1();void*subp2();四、实验指导程序结构 #include头文件pthreavoid*subp1(){ for(......){ P(…….); 打印; V(…..); } return;}subp2负责计算,如何定义?主函数:main() { 创建信号灯; 信号灯赋初值; 创建两个线程subp1、subp2; 等待两个线程运行结束; 删除信号灯; }void*subp1()主函数:main()实验三(2)Linux文件目录一、实验目的

1、了解Linux文件系统与目录操作; 2、了解Linux文件系统目录结构; 3、掌握文件和目录的程序设计方法。实验三(2)Linux文件目录一、实验目的二、实验内容

编程实现目录查询功能:功能类似ls-lR;查询指定目录下的文件及子目录信息;

显示文件的类型、大小、时间等信息;递归显示子目录中的所有文件信息。二、实验内容三、预备知识1、Linux文件属性接口#include<unistd.h>#include<sys/stat.h>#include<sys/types.h>intfstat(intfildes,structstat*buf);

返回文件描述符相关的文件的状态信息intstat(constchar*path,structstat*buf);

通过文件名获取文件信息,并保存在buf所指的结构体stat中intlstat(constchar*path,structstat*buf);

如读取到了符号连接,lstat读取符号连接本身的状态信息,而stat读取的是符号连接指向文件的信息。三、预备知识structstat{ unsignedlongst_dev; //文件所属的设备

unsignedlongst_ino; //文件相关的inode unsignedshortst_mode; //文件的权限信息和类型信息:

S_IFDIR,S_IFBLK,S_IFIFO,S_IFLINK

unsignedshortst_nlink; //硬连接的数目

unsignedshortst_uid; //文件所有者的ID

unsignedshortst_gid; //文件所有者的组ID

unsignedlongst_rdev; //设备类型

unsignedlongst_size; //文件大小

unsignedlongst_blksize; //块大小

unsignedlongst_blocks; //块数

unsignedlongst_atime; //文件最后访问时间

unsignedlongst_atime_nsec;

unsignedlongst_mtime; //最后修改内容的时间

unsignedlongst_mtime_nsec;

unsignedlongst_ctime; //文件最后修改属性的时间

unsignedlongst_ctime_nsec;

unsignedlong__unused4;

unsignedlong__unused5;};stat结构体几乎保存了所有的文件状态信息structstat{stat结构体几乎保存了所有的文件2、Linux目录结构接口#include<sys/types.h>#include<dirent.h>#include<unistd.h>opendir()DIR*opendir(constchar*name);通过路径打开一个目录,返回一个DIR结构体指针(目录流),失败返回NULL;readdir()structdirent*readdir(DIR*)读取目录中的下一个目录项,没有目录项可以读取时,返回为NULL;2、Linux目录结构接口目录项结构:structdirent{

#ifndef__USE_FILE_OFFSET64__ino_td_ino;//索引节点号

__off_td_off;//在目录文件中的偏移

#else__ino64_td_ino;__off64_td_off;#endif

unsigned

short

int

d_reclent;

//文件名的长度

unsigned

char

d_type;

//d_name所指的文件类型

char

d_name[256];

//文件名

};注:需跳过两个目录项“.”和“..”定义见/usr/include/dirent.h目录项结构:chdir()intchdir(constchar*path);改变目录,与用户通过cd命令改变目录一样,程序也可以通过chdir来改变目录,这样使得fopen(),opendir(),这里需要路径的系统调用,可以使用相对于当前目录的相对路径打开文件(目录)。closedir()intclosedir(DIR*)关闭目录流chdir()四、程序结构#include<unistd.h>#include<sys/stat.h>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<dirent.h>voidprintdir(char*dir,intdepth){DIR*dp;structdirent*entry;structstatstatbuf;if((dp=打开dir目录)不成功){

打印出错信息;

返回;}

将dir设置为当前目录;

四、程序结构while(读到一个目录项){

以该目录项的名字为参数,调用lstat得到该目录项的相关信息;if(是目录){if(目录项的名字是”..”或”.”)

跳过该目录项;

打印目录项的深度、目录名等信息递归调用printdir,打印子目录的信息,其中的depth+4;} else打印文件的深度、文件名等信息

}

返回父目录;

关闭目录项;}intmain(…){………}while(读到一个目录项){输入ls-l可以看到如下信息:drwxr-xr-x3killercatkillercat40962007-01-1116:27Desktopdrwx------8killercatkillercat40962007-01-0914:33Documentsdrwxr-xr-x2killercatkillercat40962006-11-3019:27Downloadsdrwx------4killercatkillercat40962006-12-1620:20Referencesdrwx------9killercatkillercat40962007-01-1113:34Softwaredrwxr-xr-x3killercatkillercat40962006-12-1116:39vmwaredrwx------6killercatkillercat40962007-01-1113:34Workspace输入ls-l可以看到如下信息:实验三(1)、线程同步与通信一、实验目的

1、掌握Linux下线程的概念;

2、了解Linux线程同步与通信的主要机制; 3、通过信号灯操作实现线程间的同步与互斥。实验三(1)、线程同步与通信一、实验目的二、实验内容

通过Linux多线程与信号灯机制,设计并实现计算机线程与I/O线程共享缓冲区的同步与通信。程序要求:两个线程,共享公共变量a

线程1负责计算(1到100的累加,每次加一个数)

线程2负责打印(输出累加的中间结果)二、实验内容三、预备知识1、Linux下的信号灯及其P、V操作 在Linux中信号灯是一个数据集合,可以单独使用这一集合的每个元素。 有关的系统调用命令: 1)semget:返回一个被内核指定的整型的信号灯索引。 2)semop:执行对信号灯集的操作 3)semctl:执行对信号灯集的控制操作。三、预备知识信号灯的定义:

数据结构的原型是semid_ds,在linux/sem.h中定义:

structsemid_ds{

structipc_permsem_perm;/*permissions..seeipc.h*/

time_tsem_otime;/*lastsemoptime*/

time_tsem_ctime;/*lastchangetime*/

structsem*sem_base;/*ptrtofirstsemaphoreinarray*/

structwait_queue*eventn;

structwait_queue*eventz;

structsem_undo*undo;/*undorequestsonthisarray*/

ushortsem_nsems;/*no.ofsemaphoresinarray*/

};

信号灯的定义:信号量的创建:

使用系统调用semget()创建一个新的信号量集,或者存取一个已经存在的信号量集.

原型:intsemget(key_tkey,intnsems,intsemflg);

返回值:如果成功,则返回信号量集的IPC标识符。如果失败,则返回-1.

semflg:IPC_CREAT|0666nsems:信号灯的个数信号量的创建:信号量的操作: 系统调用semop();

调用原型:intsemop(intsemid,structsembuf*sops,unsignednsops);

返回值:0,如果成功。-1,如果失敗

structsembuf{

ushortsem_num;/*semaphoreindexinarray*/

shortsem_op;/*semaphoreoperation*/

shortsem_flg;/*operationflags*/ }

sem_num将要处理的信号量的下标。 sem_op要执行的操作。

sem_flg操作标志,IPC_NOWAIT信号量的操作: 系统调用semop();

调用原型:intP操作voidP(intsemid,intindex){ structsembufsem; sem.sem_num=index;sem.sem_op=-1; sem.sem_flg=0;

//操作标记:0或IPC_NOWAIT等semop(semid,&sem,1); //1:表示执行命令的个数 return;}P操作V操作 voidV(intsemid,intindex) { structsembufsem; sem.sem_num=index;sem.sem_op=1;sem.sem_flg=0; semop(semid,&sem,1); return; }V操作信号量的赋值:系统调用semctl()

原型:intsemctl(intsemid,intsemnum,intcmd,unionsemunarg);

返回值:如果成功,则为一个正数。 参数cmd中可以使用的命令如下: ·IPC_RMID将信号量集从内存中删除。

·SETALL设置信号量集中的所有的信号量的值。

·SETVAL设置信号量集中的一个单独的信号量的值。

arg.val=1; semctl(semid,1,SETVAL,arg)信号量的赋值:系统调用semctl()

原型:intsem2、线程1)线程创建pthread_create(pthread_t*thread,pthread_attr_t *attr, void*(*start_routine)(void*),void*arg);2)pthread_join(pthread_tth,void**thread_retrun);作用:挂起当前线程直到由参数th指定的线程被终止为止。2、线程3、编辑、编译、调试

$vi $cc–otest-gtest.c–lpthread

$gdb3、编辑、编译、调试四、实验指导程序结构

#include头文件pthread.h、sys/types.h、linux/sem.h等 P、V操作的函数定义:

voidP(intsemid,intindex)

voidV(intsemid,intindex) 信号灯、线程句柄定义:

intsemid; pthread_tp1,p2; 线程执行函数定义:void*subp1();void*subp2();四、实验指导程序结构 #include头文件pthreavoid*subp1(){ for(......){ P(…….); 打印; V(…..); } return;}subp2负责计算,如何定义?主函数:main() { 创建信号灯; 信号灯赋初值; 创建两个线程subp1、subp2; 等待两个线程运行结束; 删除信号灯; }void*subp1()主函数:main()实验三(2)Linux文件目录一、实验目的

1、了解Linux文件系统与目录操作; 2、了解Linux文件系统目录结构; 3、掌握文件和目录的程序设计方法。实验三(2)Linux文件目录一、实验目的二、实验内容

编程实现目录查询功能:功能类似ls-lR;查询指定目录下的文件及子目录信息;

显示文件的类型、大小、时间等信息;递归显示子目录中的所有文件信息。二、实验内容三、预备知识1、Linux文件属性接口#include<unistd.h>#include<sys/stat.h>#include<sys/types.h>intfstat(intfildes,structstat*buf);

返回文件描述符相关的文件的状态信息intstat(constchar*path,structstat*buf);

通过文件名获取文件信息,并保存在buf所指的结构体stat中intlstat(constchar*path,structstat*buf);

如读取到了符号连接,lstat读取符号连接本身的状态信息,而stat读取的是符号连接指向文件的信息。三、预备知识structstat{ unsignedlongst_dev; //文件所属的设备

unsignedlongst_ino; //文件相关的inode unsignedshortst_mode; //文件的权限信息和类型信息:

S_IFDIR,S_IFBLK,S_IFIFO,S_IFLINK

unsignedshortst_nlink; //硬连接的数目

unsignedshortst_uid; //文件所有者的ID

unsignedshortst_gid; //文件所有者的组ID

unsignedlongst_rdev; //设备类型

unsignedlongst_size; //文件大小

unsignedlongst_blksize; //块大小

unsignedlongst_blocks; //块数

unsignedlongst_atime; //文件最后访问时间

unsignedlongst_atime_nsec;

unsignedlongst_mtime; //最后修改内容的时间

unsignedlongst_mtime_nsec;

unsignedlongst_ctime; //文件最后修改属性的时间

unsignedlongst_ctime_nsec;

unsignedlong__unused4;

unsignedlong__unused5;};stat结构体几乎保存了所有的文件状态信息structstat{stat结构体几乎保存了所有的文件2、Linux目录结构接口#include<sys/types.h>#include<dirent.h>#include<unistd.h>opendir()DIR*opendir(constchar*name);通过路径打开一个目录,返回一个DIR结构体指针(目录流),失败返回NULL;readdir()structdirent*readdir(DIR*)读取目录中的下一个目录项,没有目录项可以读取时,返回为NULL;2、Linux目录结构接口目录项结构:structdirent{

#ifndef__USE_FILE_OFFSET64__ino_td_ino;//索引节点号

__off_td_off;//在目录文件中的偏移

#else__ino64_td_ino;__off64_td_off;#endif

unsigned

short

int

d_reclent;

//文件名的长度

unsigned

char

d_type;

//d_name所指的文件类型

char

d_name[256];

//文件名

};注:需跳过两个目录项“.”和“..”定义见/usr/include/dirent.h目录项结构:chdir()intchdir(constchar*path);改变目录,与用户通过cd命令改变目录一样,程序也可以通过chdir来改变目录,这样使得fopen(),opendir(),这里需要路径的系统调用,可以使用相对于当前目

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论