Linux信号量机制1需求说明1.1基本需求目标:本次实验的目标是在Linux环境下实现一个多线程对临界资源的互斥操作,利用信号量实现对临界资源的保护,支持Linux下文件输入输出,提高对Linux环境下多进程、多线程、信号量机制和文件操作等知识的理解。问题描述:设有进程A、B、C,分别调用过程get、copy、put对缓冲区S和T进行操作。其中get负责从文件F_in中把数据块读入并输出缓冲区S,copy负责从S中提取数据块并复制到缓冲区T中,put负责从缓冲区T中取出信息存入到本地文件F_out中。实现get、copy、put的操作过程。功能需求:提供与用户交互的界面,用户可指定输入、输出文件以及缓冲区大小利用信号量(互斥量和条件变量)实现互斥同时产生多个get、copy和put线程,利用信号量实现多个相同功能的线程间的通信,避免临界资源的非法访问,可参考读写者问题解决方案支持文件输入、输出非功能需求:程序应有较好的容错性(即能对用户输入的命令进行判断,并对错误的命令进行错误处理)过程需求:使用vi进行代码的编写使用make工具建立工程将实现不同类别功能的函数写到不同的.c文件中,并使用makefile链接编译。OBJS=main.ocopy.oget.oput.ofile.osignalmove:$(OBJS)signalmove.hgcc$(OBJS)-osignalmove-lpthreadmain.o:main.csignalmove.hgcc-cmain.c-lpthreadcopy.o:copy.csignalmove.hgcc-ccopy.cget.o:get.csignalmove.hgcc-cget.cput.o:put.csignalmove.hgcc-cput.cfile.o:file.csignalmove.hgcc-cfile.c/**signalmove.h**Createdon:May14,2012*Author:dell*/#ifndefSIGNALMOVE_H_#defineSIGNALMOVE_H_#includestdio.h#includestdlib.h#includeunistd.h#includepthread.h#includesemaphore.h#includesignal.h#includefcntl.h#includestring.h#includectype.h//fileworksvoidfile_in();voidfile_out();//copyfromstotvoidcopy();//putandgetvoidput();voidget();sem_tread_sem;//readsem_twrite_sem;//writesem_tcopy_sem;//copypthread_mutex_tread_mutex;//pthreadmutexforreadpthread_mutex_twrite_mutex;//pthreadmutexforwritechar*data_s;//readbufferchar*data_t;//writebufferintlen;//bufferlengthchar*filename_out;//name_outchar*filename_in;//name_inintresult;intresult_copy;#endif/*SIGNALMOVE_H_*//**main.c**Createdon:May14,2012*Author:dell*/#includesignalmove.hintisdigit_all(char*str){while(*str!='\0'){if(!isdigit(*str++))return0;}return1;}//signaloutvoidHandlesignal(intsigno){printf(endprogram!\n,signo);exit(0);}voidmain(intargc,char*argv[]){if(argc!=4){printf(errorinput!1.filename_in,2.filename_out,3,lengthofbuffer\n);exit(0);}if(isdigit_all(argv[3])==0){printf(errorinput!1.filename_in,2.filename_out,3,lengthofbuffer\n);printf(errorlengthofbuffermustbedigit!\n);exit(0);}result_copy=0;filename_in=argv[1];filename_out=argv[2];len=atoi(argv[3]);intthread_i=0;data_s=(char*)malloc(len*sizeof(char));data_t=(char*)malloc(len*sizeof(char));if(signal(SIGINT,Handlesignal)==SIG_ERR){printf(errorsignalout\n);}pthread_tread_pthread;pthread_tcopy_pthread;pthread_twrite_pthread;//semlockintini1=sem_init(&read_sem,0,1);intini2=sem_init(&write_sem,0,0);intini5=sem_init(©_sem,0,0);if(ini1&&ini2&&ini5!=0){printf(semerror\n);exit(1);}//mutexlockintini3=pthread_mutex_init(&read_mutex,NULL);intini4=pthread_mutex_init(&write_mutex,NULL);if(ini3&&ini4!=0){printf(mutexerror\n);exit(1);}intthread_1=pthread_create(&read_pthread,NULL,(void*)&get,(void*)(&thread_i));if(thread_1!=0){printf(readthreadcreateerror!\n);exit(1);}thread_i++;intthread_2=pthread_create(©_pthread,NULL,(void*)©,(void*)(&thread_i));if(thread_2!=0){printf(copythreadcreateerror!\n);exit(1);}thread_i++;intthread_3=pthread_create(&write_pthread,NULL,(void*)&put,(void*)(&thread_i));if(thread_3!=0){printf(writethreadcreateerror!\n);exit(1);}pthread_join(read_pthread,NULL);pthread_join(copy_pthread,NULL);pthread_join(write_pthread,NULL);free(data_s);free(data_t);exit(0);}/**file.c**Createdon:May14,2012*Author:dell*fileworks*/#includesignalmove.hvoidfile_in(intfd,char*data,intlen){while(1){sem_wait(&read_sem);pthread_mutex_lock(&read_mutex);printf(data_in..........\n);if(lseek(fd,0,SEEK_CUR)==-1){printf(lseekfailed!\n);}if((result=read(fd,data,len))==-1){printf(readerror!\n);}inti=0,j=0;printf(data_in..........complete\n);pthread_mutex_unlock(&read_mutex);sem_post(©_sem);if(resultlen){len=result;result=0;break;}}}voidfile_out(intfd,char*data,intlen){while(1){sem_wait(&write_sem);pthread_mutex_lock(&write_mutex);printf(data_out..........\n);if(write(fd,data,len)==-1){printf(writeerror!\n);}printf(data_out..........complete\n);pthread_mutex_unlock(&write_mutex);if(result_copy==1){break;}}}/**put.c**Createdon:May14,2012*Author:dell*/#includesignalmove.hvoidput(){intfd=open(filename_out,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);if(fd==-1){printf(openfilewrong!\n);exit(0);}file_out(fd,data_t,len);}/**get.c**Createdon:May14,2012*Author:dell*/#includesignalmove.hvoidget(){intfd=open(filename_in,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);if(fd==-1){printf(openfilewrong!\n);exit(0);}file_in(fd,data_s,len);}/**copy.c**Createdon:May14,2012*Author:dell*copydatafromStoT*/#includesignalmove.hvoidcopy(){while(1){sem_wait(©_sem);pthread_mutex_lock(&read_mutex);pthread_mutex_lock(&write_mutex);printf(copy..........\n);strcpy(data_t,data_s);inti=0;for(;ilen;i++){data_s[i]='';}printf(copy..........complete\n);pthread_mutex_unlock(&write_mutex);pthread_mutex_unlock(&read_mutex);sem_post(&write_sem);sem_post(&read_sem);if(result==0){result_copy=1;break;}}}