大作业
信号量机制
姓名:
学号:
班级:010914
日期:2012年5月日 ---Linux
23
1 需求说明
进程A、B、C,分别调用过程get、copy、put对缓冲区S和T进行操作。其中get负责从文件F_in中把数据块读入并输出缓冲区S,copy负责从S中提取数据块并复制到缓冲区T中,put负责从缓冲区T中取出信息存入到本地文件F_out中。实现get、copy、put的操作过程。
get 缓冲区S copy 缓冲区T put
功能需求:
提供与用户交互的界面,用户可指定输入、输出文件以及缓冲区大小 利用信号量实现互斥
同时产生多个get、copy和put线程,利用信号量实现多个相同功能的线程间的通
信,避免临界资源的非法访问,可参考读写者问题解决方案 支持文件输入、输出
非功能需求:
程序应有较好的容错性(即能对用户输入的命令进行判断,并对错误的命令进行错
误处理)
过程需求:
使用vi进行代码的编写 使用make工具建立工程
将实现不同类别功能的函数写到不同的.c文件中,并使用makefile链接编译。
2 设计说明 2.1 结构设计
进程1通过get函数将源文件载入缓冲区S;
进程2通过copy函数将数据从缓冲区S复制到缓冲区T内; 进程3通过put函数将缓冲区T内的数据输出到目标文件。
2.2 功能设计
1.提供与用户交互的界面,用户可指定输入、输出文件以及缓冲区大小。 2.利用信号量实现互斥。
3.同时产生多个get、copy和put线程,利用信号量实现多个相同功能的线程间的通信,避免临界资源的非法访问。
3 测试和使用说明 3.1 使用说明
1、执行make命令,编译程序test; 2、执行test;
3、输入源文件的路径 4、输入目标文件的文件名 5、输入缓冲区大小 6、程序执行完毕
3.2 测试说明
执行make命令,编译test。
输入文件fin内容如上图。
./fin
运行可执行程序test,程序请求用户指定输入文件、输出文件和缓冲区大小。程序获取用户输入后,根据设计要求将输入文件的内容复制到输出文件中,并显示执行过程和执行状态。
输出文件fout如上图所示。
4 程序清单
头文件para.h
#include #include #define PERMS S_IRUSR|S_IWUSR FILE *fin,*fout; int S_sem,S_n,S_e,T_sem,T_n,T_e; int end_mark; struct sembuf semwait,semsignal; C文件sem.c #include sem->sem_num = semnum; sem->sem_op = semop; sem->sem_flg = semflg; } int del_semaphore(int semid) { #if 1 return semctl(semid,0,IPC_RMID); #endif } C文件get.c #include #include void get(int BUF_SIZE) { long length,times; int S_segment_id; char *S_shared_memory; char string[1024]; struct shmid_ds shmbuffer; memset(string,'\\0',1024); S_segment_id = shmget(99,BUF_SIZE,IPC_CREAT|0666); S_shared_memory = (char *)shmat(S_segment_id,NULL,0); shmctl(S_segment_id,IPC_STAT,&shmbuffer); fseek(fin,0,SEEK_END); length = ftell(fin); fseek(fin,0,SEEK_SET); times = length / BUF_SIZE; while( times ) { fread(string,BUF_SIZE,1,fin); semop(S_e,&semwait,1); semop(S_sem,&semwait,1); strcpy(S_shared_memory,string); printf(\"Get File_input to Buffer_S OK,%s\\n\ semop(S_sem,&semsignal,1); semop(S_n,&semsignal,1); times--; } printf(\"End Getting.\\n\"); shmdt(S_shared_memory); } C文件copy.c #include void copy(int BUF_SIZE) { char string[1024]; int T_segment_id; char *T_shared_memory; struct shmid_ds T_shmbuffer; T_segment_id = shmget(100,BUF_SIZE,IPC_CREAT|0666); T_shared_memory = (char *)shmat(T_segment_id,NULL,0); shmctl(T_segment_id,IPC_STAT,&T_shmbuffer); int S_segment_id; char *S_shared_memory; struct shmid_ds S_shmbuffer; S_segment_id = shmget(99,BUF_SIZE,IPC_CREAT|0666); S_shared_memory = (char *)shmat(S_segment_id,NULL,0); shmctl(S_segment_id,IPC_STAT,&S_shmbuffer); while(!end_mark) { } semop(S_n,&semwait,1); semop(S_sem,&semwait,1); strcpy(string,S_shared_memory); memset(S_shared_memory,'\\0',BUF_SIZE); semop(S_sem,&semsignal,1); semop(S_e,&semsignal,1); semop(T_e,&semwait,1); semop(T_sem,&semwait,1); strcpy(T_shared_memory,string); printf(\"Copy Buffer_S to Buffer_T OK,%s\\n\ semop(T_sem,&semsignal,1); semop(T_n,&semsignal,1); } printf(\"End Copy.\\n\"); shmdt(S_shared_memory); shmdt(T_shared_memory); C文件put.c #include void put(int BUF_SIZE) { int T_segment_id; char *T_shared_memory; struct shmid_ds T_shmbuffer; } T_segment_id = shmget(100,BUF_SIZE,IPC_CREAT|0666); T_shared_memory = (char *)shmat(T_segment_id,NULL,0); shmctl(T_segment_id,IPC_STAT,&T_shmbuffer); while(!end_mark) { semop(T_n,&semwait,1); semop(T_sem,&semwait,1); if (fprintf(fout,\"%s\ printf(\"Put Buffer_T to File_input OK,%s\\n\ memset(T_shared_memory,'\\0',BUF_SIZE); semop(T_sem,&semsignal,1); semop(T_e,&semsignal,1); } printf(\"End Putting.\\n\"); shmdt(T_shared_memory); C文件main.c #include #include \"para.h\" void stop() { end_mark = 1; } void main() { int BUF_SIZE; char *input = (char *)malloc(1024); memset(input,'\\0',1024); init_semaphore_struct(&semwait,0,-1,0); init_semaphore_struct(&semsignal,0,1,0); S_sem = semget(IPC_PRIVATE,1,PERMS); S_n = semget(IPC_PRIVATE,1,PERMS); S_e = semget(IPC_PRIVATE,1,PERMS); T_sem = semget(IPC_PRIVATE,1,PERMS); T_n = semget(IPC_PRIVATE,1,PERMS); T_e = semget(IPC_PRIVATE,1,PERMS); semop(S_e,&semsignal,1); semop(S_sem,&semsignal,1); semop(T_e,&semsignal,1); semop(T_sem,&semsignal,1); pid_t pid1,pid2; while (1) { printf(\"Please input the path of File_input:\"); scanf(\"%s\ if ( (fin = fopen(input,\"rt\")) == NULL ) printf(\"Can't find the file.\\n\"); else break; } while (1) { printf(\"Please input the path of File_output:\"); scanf(\"%s\ if ( (fout = fopen(input,\"wt\")) == NULL ) printf(\"Can't find the file.\\n\"); else break; } while (1) { printf(\"Please input the size of Buffer (interger less than 1024):\"); scanf(\"%d\ if ( BUF_SIZE > 1024 ) printf(\"The size of Buffer is too big.\\n\"); else break; } while((pid1 = fork()) == -1); if (pid1 > 0) { get(BUF_SIZE); sleep(1); kill(pid1,10); wait(0); wait(0); fclose(fin); fclose(fout); del_semaphore(S_sem); del_semaphore(S_n); del_semaphore(S_e); del_semaphore(T_sem); del_semaphore(T_n); del_semaphore(T_e); exit(0); } else { while((pid2 = fork()) == -1); if (pid2 > 0) { signal(10,stop); copy(BUF_SIZE); kill(pid2,12); } } wait(0); exit(0); } else { signal(12,stop); put(BUF_SIZE); exit(0); } makefile文件makefile test:main.o sem.o get.o copy.o put.o cc main.o sem.o get.o copy.o put.o -o test main.o:main.c para.h cc -c main.c sem.o:sem.c cc -c sem.c get.o:get.c para.h cc -c get.c copy.o:copy.c para.h cc -c copy.c put.o:put.c para.h cc -c put.c clean: rm -f *.o 因篇幅问题不能全部显示,请点此查看更多更全内容