1> 将互斥机制的代码实现重新敲一遍
#include <myhead.h>
int num=520;//定义一个全局变量
pthread_mutex_t mutex;//创建锁
//线程1任务
void *task1(void *arg)
{
puts("任务1");
pthread_mutex_lock(&mutex);//上锁
num=1314;
sleep(1);
printf("task1num=%d\n",num);
pthread_mutex_unlock(&mutex);//解锁
}
//线程2任务
void *task2(void *arg)
{
puts("任务2");
pthread_mutex_lock(&mutex);//上锁
num++;
sleep(1);
printf("task2num=%d\n",num);
pthread_mutex_unlock(&mutex);//解锁
}
int main(int argc, const char *argv[])
{
//初始化锁
pthread_mutex_init(&mutex, NULL);
//创建两个线程tdi1,tdi2
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,task1,NULL)!=0)
{
printf("tid1 create error\n");
return 0;
}
if(pthread_create(&tid2,NULL,task2,NULL)!=0)
{
printf("tid2 create error\n");
return 0;
}
//以阻塞的形式回收线程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销锁
pthread_mutex_destroy(&mutex);
return 0;
}
2> 将无名信号量的代码实现重新敲一遍
#include <myhead.h>
sem_t sem;//创建无名变量
//线程任务1生产特斯拉
void *task1(void *arg)
{
int num=3;
while(num--)
{
sleep(1);
puts("生产特斯拉");
sem_post(&sem);//value值从0变为1
}
pthread_exit(NULL);//退出线程
}
//线程2购买特斯拉
void *task2(void *arg)
{
int num=3;
while(num--)
{
sem_wait(&sem);//value值从1变为0;
puts("购买特斯拉");
}
pthread_exit(NULL);//退出线程
}
int main(int argc, const char *argv[])
{
sem_init(&sem,0,0);//初始化无名变量并让value值变为0
pthread_t tid1,tid2;//创建一个生产者线程,一个消费者线程
if(pthread_create(&tid1,NULL,task1,NULL)!=0)
{
printf("tid1 create error\n");
return 0;
}
if(pthread_create(&tid2,NULL,task2,NULL)!=0)
{
printf("tid2 create error\n");
return 0;
}
//回收线程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁无名变量
sem_destroy(&sem);
return 0;
}
3> 将条件变量的代码实现重新敲一遍
#include<myhead.h>
//创建条件变量
pthread_cond_t cond;
//创建互斥锁
pthread_mutex_t mutex;
//生产者线程
void *task1(void *arg)
{
int num = 5;
while(num --)
{
sleep(1);
printf("生产了一辆特斯拉\n");
//唤醒一个消费者
pthread_cond_signal(&cond);
}
pthread_exit(NULL); //退出线程
}
//消费者线程
void *task2(void *arg)
{
pthread_mutex_lock(&mutex);//上锁
pthread_cond_wait(&cond, &mutex);//等待唤醒
printf("%#lx:消费了一辆特斯拉\n", pthread_self());
pthread_mutex_unlock(&mutex);//解锁
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
//创建4个线程,分别是一个生产者和三个消费者
pthread_t tid1, tid2, tid3,tid4;
if(pthread_create(&tid1, NULL, task1, NULL) != 0)
{
printf("tid1 create error\n");
return 0;
}
if(pthread_create(&tid2, NULL, task2, NULL) != 0)
{
printf("tid2 create error\n");
return 0;
}
if(pthread_create(&tid3, NULL, task2, NULL) != 0)
{
printf("tid3 create error\n");
return 0;
}
if(pthread_create(&tid4, NULL, task2, NULL) != 0)
{
printf("tid4 create error\n");
return 0;
}
//回收线程资源
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
pthread_join(tid4, NULL);
pthread_cond_destroy(&cond);//销毁条件变量
pthread_mutex_destroy(&mutex);//销毁锁
return 0;
}
4> 将无名管道的代码实现重新敲一遍
#include <myhead.h>
int main(int argc, const char *argv[])
{
int pipefd[2]={0};//获取管道文件的读端和写端
if(pipe(pipefd)==-1)
{
perror("pipe error");
return -1;
}
pid_t pid =fork();//创建一个进程
if(pid>0)//父进程
{
close(pipefd[0]);//关闭管道文件的读端
char wbuf[100]="";
while(1)
{
bzero(wbuf,sizeof(wbuf));//清空容器
fgets(wbuf,sizeof(wbuf),stdin);//从终端获取内容
wbuf[strlen(wbuf)-1]=0;
write(pipefd[1],wbuf,strlen(wbuf));//把容器内容写进管道文件
if(strcmp(wbuf,"end")==0)//结束传递数据的条件
{
break;
}
}
close(pipefd[1]);//关闭管道文件的写端
wait(NULL);//阻塞回收子进程
}
else if(pid==0)//子进程
{
char rbuf[100]="";
while(1)
{
bzero(rbuf,sizeof(rbuf));
read(pipefd[0],rbuf,sizeof(rbuf));//从管道文件中读取内容
if(strcmp(rbuf,"end")==0)
{
break;
}
printf("从管道文件中读取的内容:%s\n",rbuf);
}
close(pipefd[0]);
exit(EXIT_SUCCESS);//退出子进程
}
else
{
perror("fork error");
return -1;
}
return 0;
}
5> 将有名管道的代码实现重新敲一遍
创建管道文件的代码:
#include <myhead.h>
int main(int argc, const char *argv[])
{
//创建一个管道文件
if(mkfifo("./管道文件",0664)==-1)
{
perror("mkfifo error");
return -1;
}
getchar();//阻塞,实现多次输入和输出
system("rm 管道文件");
return 0;
}
传输源文件代码:
#include <myhead.h>
int main(int argc, const char *argv[])
{
//以只写的形式打开管道文件
int wfd=-1;
if((wfd=open(argv[1],O_WRONLY))==-1)
{
perror("open error");
return -1;
}
char wbuf[1024];
while(1)
{
printf("请输入要传输的内容:");
fgets(wbuf,sizeof(wbuf),stdin);//从终端获取传输内容
wbuf[strlen(wbuf)-1]='\0';
//将传输的内容写进管道中
write(wfd,wbuf,sizeof(wbuf));
if(strcmp(wbuf,"end")==0)//结束传输数据条件
{
break;
}
}
close(wfd);//关闭管道文件
return 0;
}
接收文件代码:
#include <myhead.h>
int main(int argc, const char *argv[])
{
//以只读的形式打开管道文件
int rfd=-1;
if((rfd=open(argv[1],O_RDONLY))==-1)
{
perror("open error");
return -1;
}
char rbuf[1024];
while(1)
{
bzero(rbuf,sizeof(rbuf));//清空数组
//读取管道中的文件
read(rfd,rbuf,sizeof(rbuf));
if(strcmp(rbuf,"end")==0)//结束传输数据条件
{
break;
}
//将从管道中读取的数据输出到终端
printf("从管道文件中读取的内容:%s\n",rbuf);
}
close(rfd);//关闭管道文件
return 0;
}
6> 使用有名管道完成两个进程的相互通信(提示:可以使用多进程或多线程完成)
创建管道文件代码
#include <myhead.h>
int main(int argc, const char *argv[])
{
//创建两个管道文件
if(mkfifo("./管道文件1",0664)==-1)
{
perror("mkfifo error");
return -1;
}
if(mkfifo("./管道文件2",0664)==-1)
{
perror("mkfifo error");
return -1;
}
getchar();//阻塞,实现多次输入和输出
system("rm 管道文件1");
system("rm 管道文件2");
return 0;
}
用户1代码:
#include <myhead.h>
int main(int argc, const char *argv[])
{
pid_t pid = fork();
if(pid<0)
{
perror("fork error");
}
else if(pid==0)//子进程读
{
//以只读的形式打开管道文件2
int rfd=-1;
if((rfd=open(argv[2],O_RDONLY))==-1)
{
perror("open error");
return -1;
}
char rbuf[1024];
while(1)
{
bzero(rbuf,sizeof(rbuf));//清空数组
//读取管道中的文件
read(rfd,rbuf,sizeof(rbuf));
if(strcmp(rbuf,"end")==0)//结束传输数据条件
{
close(rfd);//关闭管道文件
break;
}
//将从管道2中读取的数据输出到终端
printf("从管道文件中读取的内容:%s\n",rbuf);
}
}
else//父进程写
{
//以只写的形式打开管道文件1
int wfd=-1;
if((wfd=open(argv[1],O_WRONLY))==-1)
{
perror("open error");
return -1;
}
char wbuf[1024];
while(1)
{
fgets(wbuf,sizeof(wbuf),stdin);//从终端获取传输内容
wbuf[strlen(wbuf)-1]='\0';
//将传输的内容写进管道中
write(wfd,wbuf,sizeof(wbuf));
if(strcmp(wbuf,"end")==0)//结束传输数据条件
{
close(wfd);
break;
}
}
}
return 0;
}
用户2代码:
#include <myhead.h>
int main(int argc, const char *argv[])
{
pid_t pid = fork();
if(pid<0)
{
perror("fork error");
}
else if(pid==0)//子进程读
{
//以只读的形式打开管道文件1
int rfd=-1;
if((rfd=open(argv[1],O_RDONLY))==-1)
{
perror("open error");
return -1;
}
char rbuf[1024];
while(1)
{
bzero(rbuf,sizeof(rbuf));//清空数组
//读取管道中的文件
read(rfd,rbuf,sizeof(rbuf));
if(strcmp(rbuf,"end")==0)//结束传输数据条件
{
close(rfd);//关闭管道文件
break;
}
//将从管道中1读取的数据输出到终端
printf("从管道文件中读取的内容:%s\n",rbuf);
}
}
else//父进程写
{
//以只写的形式打开管道文件2
int wfd=-1;
if((wfd=open(argv[2],O_WRONLY))==-1)
{
perror("open error");
return -1;
}
char wbuf[1024];
while(1)
{
fgets(wbuf,sizeof(wbuf),stdin);//从终端获取传输内容
wbuf[strlen(wbuf)-1]='\0';
//将传输的内容写进管道中
write(wfd,wbuf,sizeof(wbuf));
if(strcmp(wbuf,"end")==0)//结束传输数据条件
{
close(wfd);//关闭管道文件
break;
}
}
}
return 0;
}
思维导图: