作业
1> 使用有名管道,完成两个进程的相互通信
#include
int main(int argc, const char *argv[])
{
if(mkfifo("pipefile1",0664)==-1)
{
perror("pipefifo1 error");
return -1;
}
if(mkfifo("pipefile2",0664)==-1)
{
perror("pipefifo2 error");
return -1;
}
getchar();
system("rm pipefile1");
system("rm pipefile2");
return 0;
}
//写端
#include
void *task_write(void *arg)
{
pthread_t pipe1=*(pthread_t *)arg;
char wbuf[128]="";
while(1)
{
printf("写端->");
fgets(wbuf,sizeof(wbuf),stdin);
wbuf[strlen(wbuf)-1]='\0';
write(pipe1,wbuf,sizeof(wbuf));
if(strcmp(wbuf,"quit")==0)
{
break;
}
}
}
void *task_read(void *arg)
{
pthread_t pipe2=*(pthread_t *)arg;
char rbuf[128]="";
while(1)
{
bzero(rbuf,sizeof(rbuf));
read(pipe2,rbuf,sizeof(rbuf));
printf("读端发来一条消息->%s\n",rbuf);
if(strcmp(rbuf,"quit")==0)
{
puts("读端退出聊天");
break;
}
}
}
int main(int argc, const char *argv[])
{
pthread_t tid1=-1,tid2=-1;
int pipe1=-1,pipe2=-1;
if((pipe1=open("./pipefile1",O_WRONLY))==-1||(pipe2=open("./pipefile2",O_RDONLY))==-1)
{
perror("pipefile open error");
return -1;
}
if(pthread_create(&tid1,NULL,task_write,(void *)&pipe1)!=0)
{
perror("pipe2 create error");
return -1;
}
if(pthread_create(&tid2,NULL,task_read,(void *)&pipe2)!=0)
{
perror("pipe1 create error");
return -1;
}
//回收进程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//关闭文件
close(pipe1);
close(pipe2);
return 0;
}
//读端
#include
void *task_read(void *arg)
{
pthread_t pipe1=*(pthread_t *)arg;
char rbuf[128]="";
while(1)
{
bzero(rbuf,sizeof(rbuf));
read(pipe1,rbuf,sizeof(rbuf));
printf("写端发来一条消息->%s\n",rbuf);
if(strcmp(rbuf,"quit")==0)
{
puts("写端退出聊天");
break;
}
}
}
void *task_write(void *arg)
{
pthread_t pipe2=*(pthread_t *)arg;
char wbuf[128]="";
while(1)
{
printf("读端->");
fgets(wbuf,sizeof(wbuf),stdin);
wbuf[strlen(wbuf)-1]='\0';
write(pipe2,wbuf,sizeof(wbuf));
if(strcmp(wbuf,"quit")==0)
{
break;
}
}
}
int main(int argc, const char *argv[])
{
pthread_t tid1=-1,tid2=-1;
int pipe1=-1,pipe2=-1;
if((pipe1=open("./pipefile1",O_RDONLY))==-1||(pipe2=open("./pipefile2",O_WRONLY))==-1)
{
perror("pipefile open error");
return -1;
}
if(pthread_create(&tid1,NULL,task_read,(void *)&pipe1)!=0)
{
perror("pipe1 create error");
return -1;
}
if(pthread_create(&tid2,NULL,task_write,(void *)&pipe2)!=0)
{
perror("pipe2 create error");
return -1;
}
//回收进程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//关闭文件
close(pipe1);
close(pipe2);
return 0;
}
2> 使用无名管道完成父子进程间的通信
#include
int main(int argc, const char *argv[])
{
pid_t pid=-1;//存放fork返回的进程pid
int pipefd[2];//数组存放创建无名管道返回的两个文件描述符
//创建无名管道文件
if(pipe(pipefd)==-1)
{
perror("pipe error");
return -1;
}
pid=fork();
if(pid>0)
{
//写端首先关闭读端
close(pipefd[0]);
char wbuf[128]="";
//父进程作为写端
while(1)
{
fgets(wbuf,sizeof(wbuf),stdin);
wbuf[strlen(wbuf)-1]='\0';
write(pipefd[1],wbuf,sizeof(wbuf));
if(strcmp(wbuf,"quit")==0)
{
puts("退出");
break;
}
}
//写端其次关闭写端
close(pipefd[1]);
}
else if(pid==0)
{
//读端首先关闭写端
close(pipefd[1]);
char rbuf[128]="";
//子进程作为读端
while(1)
{
read(pipefd[0],rbuf,sizeof(rbuf));
printf("父进程发来一条消息->%s\n",rbuf);
if(strcmp(rbuf,"quit")==0)
{
puts("退出");
break;
}
}
//读端其次关闭读端
close(pipefd[1]);
//关闭子进程
exit(EXIT_SUCCESS);
}
else
{
perror("fork error");
return -1;
}
//进程回收
wait(NULL);
//waitpid(-1,NULL,0);
return 0;
}
3> 使用标准IO完成两个文件的拷贝
#include
int main(int argc, const char *argv[])
{
if(argc!=3)
{
printf("check your input!\n");
return -1;
}
FILE *srcfp;
FILE *destfp;
if((srcfp=fopen(argv[1],"r"))==NULL)//只读形式打开源文件 fopen打开失败返回NULL
{
perror("srcfp fopen error");
return -1;
}
if((destfp=fopen(argv[2],"w+"))==NULL)//读写形式打开目标文件 不存在自动创建
{
perror("destfp fopen error");
return -1;
}
//开始复制文件
char buf[128]="";
while(!ferror(srcfp)&&!feof(srcfp))//feof读取到文件结尾返回真 ferror读取错误返回真
{
fread(buf,sizeof(buf),1,srcfp);//源文件中读取到
fwrite(buf,sizeof(buf),1,destfp);//写到目标文件中
}
//关闭文件
fclose(srcfp);
fclose(destfp);
return 0;
}
4> 使用文件IO实现两个文件的拷贝
#include
int main(int argc, const char *argv[])
{
if(argc!=3)
{
printf("check your input!\n");
return -1;
}
int srcfd=-1,destfd=-1;
if((srcfd=open(argv[1],O_RDONLY))==-1)//只读打开源文件
{
perror("srcfd open error");
return -1;
}
if((destfd=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)//W形式打开目标文件
{
perror("destfd open error");
return -1;
}
//复制粘贴文件
char buf[128]="";
while(read(srcfd,buf,sizeof(buf))!=0)
{
write(destfd,buf,sizeof(buf));
}
//关闭文件
close(srcfd);
close(destfd);
return 0;
}
5> 使用多进程完成两个文件的拷贝
#include
int length(const char *src,const char *dest)
{
//打开两个文件
int srcfd=-1,destfd=-1,len=0;
if((srcfd=open(src,O_RDONLY))==-1)
{
perror("srcfd open error!\n");
return -1;
}
if((destfd=open(dest,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
{
perror("destfd open error!\n");
return -1;
}
len=lseek(srcfd,0,SEEK_END);
//关闭文件
close(srcfd);
close(destfd);
printf("len->%d\n",len);
return len;
}
int copy_fork(const char *src,const char *dest,int start,int len)
{
//打开两个文件
int srcfd=-1,destfd=-1;
if((srcfd=open(src,O_RDONLY))==-1)
{
perror("srcfd open error!\n");
return -1;
}
if((destfd=open(dest,O_WRONLY))==-1)
{
perror("destfd open error!\n");
return -1;
}
//两个文件都移动到指定位置同步复制
lseek(srcfd,start,SEEK_SET);
lseek(destfd,start,SEEK_SET);
char buf[128]="";
int ret=0,sum=0;
while(1)
{
ret=read(srcfd,buf,sizeof(buf));
sum+=ret;
if(ret==0||sum>=len)//read不到内容时或者sum超过长度
{
write(destfd,buf,ret-(sum-len));
break;
}
write(destfd,buf,ret);
}
//关闭文件
close(srcfd);
close(destfd);
return 0;
}
int main(int argc, const char *argv[])
{
if(argc!=3)
{
printf("check your input!\n");
return -1;
}
int len=length(argv[1],argv[2]);
pid_t pid=-1;
pid=fork();
if(pid>0)//父进程
{
copy_fork(argv[1],argv[2],0,len/2);
puts("前一半拷贝完成!");
}
else if(pid==0)//子进程
{
copy_fork(argv[1],argv[2],len/2,len-len/2);
puts("后一半拷贝完成!");
//退出子进程
exit(EXIT_SUCCESS);
}
else
{
perror("fork error!\n");
return -1;
}
//回收进程资源
wait(NULL);
puts("多进程拷贝完成!");
return 0;
}
6> 使用多线程完成两个文件的拷贝
#include
typedef struct xxx
{
const char* src;
const char* dest;
int start;
int len;
}info;
int length(const char *src,const char *dest)
{
//打开两个文件
int srcfd=-1,destfd=-1,len=0;
if((srcfd=open(src,O_RDONLY))==-1)
{
perror("srcfd open error!\n");
return -1;
}
if((destfd=open(dest,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
{
perror("destfd open error!\n");
return -1;
}
len=lseek(srcfd,0,SEEK_END);
//关闭文件
close(srcfd);
close(destfd);
printf("len->%d\n",len);
return len;
}
void *task_copy(void *arg)
{
info buf=*(info *)arg;
//打开两个文件
int srcfd=-1,destfd=-1;
if((srcfd=open(buf.src,O_RDONLY))==-1)
{
perror("srcfd open error!\n");
return NULL;
}
if((destfd=open(buf.dest,O_WRONLY))==-1)
{
perror("destfd open error!\n");
return NULL;
}
//开始复制
lseek(srcfd,buf.start,SEEK_SET);
lseek(destfd,buf.start,SEEK_SET);
char rbuf[128]="";
int ret=0,sum=0;
while(1)
{
ret=read(srcfd,rbuf,sizeof(rbuf));
sum+=ret;
if(ret==0||sum>=buf.len)
{
write(destfd,rbuf,ret-(sum-buf.len));
break;
}
write(destfd,rbuf,ret);
}
//关闭文件
close(srcfd);
close(destfd);
}
int main(int argc, const char *argv[])
{
if(argc!=3)
{
printf("check your input!\n");
return -1;
}
int len=length(argv[1],argv[2]);
pthread_t tid1=-1,tid2=-1;
info buf1={argv[1],argv[2],0,len/2};
info buf2={argv[1],argv[2],len/2,len-len/2};
if(pthread_create(&tid1,NULL,task_copy,(void *)&buf1)!=0)
{
perror("pthread_create1 error!\n");
return -1;
}
if(pthread_create(&tid2,NULL,task_copy,(void *)&buf2)!=0)
{
perror("pthread_create2 error!\n");
return -1;
}
//回收线程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
puts("多线程拷贝完成!");
return 0;
}
7> 将互斥锁的案例重新写一遍
#include
int money=1000;//临界资源
pthread_mutex_t mutex;//定义一个锁
void *task_spend(void *arg)
{
int pay;
while(1)
{
sleep(1);
pay=rand()%100+1;//1-100随机数
//上锁:获取锁资源
pthread_mutex_lock(&mutex);
//临界区
if((money-=pay)<=0)
{
break;
}
printf("线程%#lx->花费%d,当前剩余%d\n",pthread_self(),pay,money);
//开锁:释放锁资源
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_mutex_init(&mutex,NULL);//初始化锁
int n,i;
printf("input n person to spend moeny->");
scanf("%d",&n);
pthread_t tid[n];
while(i
8> 将无名信号量实现生产者消费者程序重新实现一遍
#include
sem_t sem;//定义一个无名信号量
void *task_buycar(void *arg)
{
while(1)
{
sleep(1);
printf("买了一辆车!\n");
//释放无名信号量
sem_post(&sem);
}
}
void *task_pickcar(void *arg)
{
while(1)
{
//获取无名信号量
sem_wait(&sem);
printf("准备取提车!\n");
}
}
int main(int argc, const char *argv[])
{
sem_init(&sem,0,0);//初始化
pthread_t tid1=-1,tid2=-1;
if(pthread_create(&tid1,NULL,task_buycar,NULL)!=0)
{
perror("pthread_create1 error!\n");
return -1;
}
if(pthread_create(&tid2,NULL,task_pickcar,NULL)!=0)
{
perror("pthread_create2 error!\n");
return -1;
}
//回收线程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁无名信号量
sem_destroy(&sem);
return 0;
}
9> 将条件变量实现生产者消费者程序重新实现一遍
#include
pthread_cond_t cond;//定义条件变量
pthread_mutex_t mutex;//定义互斥锁
void *task_produce(void *arg)
{
int n=10;
while(n--)
{
printf("生产\n");
//唤醒一个消费者
pthread_cond_signal(&cond);
}
//退出线程
pthread_exit(NULL);
}
void *task_consume(void *arg)
{
//上锁
pthread_mutex_lock(&mutex);
//加入队列
pthread_cond_wait(&cond,&mutex);
//开锁
pthread_mutex_unlock(&mutex);
printf("线程->%#lx,消费\n",pthread_self());
//退出线程
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_cond_init(&cond,NULL);//初始化条件变量
pthread_mutex_init(&mutex,NULL);//初始化互斥锁
int n;
printf("input n->");
scanf("%d",&n);
pthread_t tid[n];
if(pthread_create(&tid[0],NULL,task_produce,NULL)!=0)
{
perror("pthread_create tid[0] error!\n");
return -1;
}
int i=1;
while(i