IO进程线程作业day5

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)//结束传输数据条件
			{
				break;
			}
			//将从管道2中读取的数据输出到终端
			printf("从管道文件中读取=的内容:%s\n",rbuf);
		}
		close(rfd);//关闭管道文件
		exit(EXIT_SUCCESS);
	}
	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;
			}
		}
	}
	wait(NULL);
	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)//结束传输数据条件
			{
					break;
			}
			//将从管道中1读取的数据输出到终端
			printf("从管道文件中读取的内容:%s\n",rbuf);
		}
		close(rfd);//关闭管道文件
		exit(EXIT_SUCCESS);
	}
	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;
			}
		}
	}
	wait(NULL);
	return 0;
}

 

 思维导图:

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值