Day7(IO进程线程)

作业

1.将一个文件中的数据打印到终端上,类似cat一个文件。要求如下:
a.A线程读取文件中的数据
b.B线程将A线程读取到的数据打印到终端上
c.文件打印完毕后,结束进程。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

sem_t sem1, sem2;
int res;
int fp;
off_t size;
char c;

//B线程写到终端上
void *CallBack_printf(void *arg)
{
	int i=0;
	while(1)
	{	
		if(res < 0)
			break;
		sem_wait(&sem2);

		write(1, &c, res);

		sem_post(&sem1);
	}

	pthread_exit(NULL);
}

//A线程读取文件中的数据
void *CallBack_read(void *arg)
{
	while(1)
	{
		sem_wait(&sem1);
	
		if((res=read(fp, &c, 1)) < 0)
		{
			perror("read");
			pthread_exit(NULL);
		}
		if(res==0)
		{
			break;
		}

		sem_post(&sem2);
	}

	pthread_exit(NULL);
}



int main(int argc, const char *argv[])
{
	//打开一个文件
	if((fp = open("./01_cond.c", O_RDONLY)) < 0)
	{
		perror("open");
		return -1;
	}
	if(fp < 0)
	{
		perror("open");
		return -1;
	}

	//偏移量
	size = lseek(fp, 0, SEEK_END);
	printf("size = %ld\n", size);
	lseek(fp, 0, SEEK_SET);
	
	//创建两个线程
	pthread_t tid1;
	pthread_t tid2;
	if(pthread_create(&tid1, NULL, CallBack_read, NULL) < 0)
	{
		fprintf(stderr, "pthread_create failedi\n");
		return -1;
	}

	if(pthread_create(&tid2, NULL, CallBack_printf, NULL) < 0)
	{
		fprintf(stderr, "pthread_create failed\n");
		return -1;
	}
	
	//创建2个信号量
	if(sem_init(&sem1, 0, 1) < 0)
	{
		perror("sem_init");
		return -1;
	}
	if(sem_init(&sem2, 0, 0) < 0)
	{
		perror("sem_init");
		return -1;
	}

	//阻塞主线程销毁
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);

	//关闭文件
	close(fp);

	//销毁信号量
	sem_destroy(&sem1);
	sem_destroy(&sem2);
	printf("打印成功\n");
	
	return 0;
}

输出结果:

ubuntu@ubuntu:Day7$ gcc 01_homework.c -pthread
ubuntu@ubuntu:Day7$ ./a.out 
size = 1872
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

//临界资源
char buf[] = "1234567";

//互斥锁的建立
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//创建条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int flag = 0; 	//0:打印, 1:倒置

void* CallBack_printf(void *arg)
{
	while(1)
	{
		/******************临界区***************/
		//上锁
		pthread_mutex_lock(&mutex);

		if(flag != 0)
		{
			//可以解开互斥锁,同时阻塞当前线程,让线程进入休眠操作
			//等待被唤醒
			pthread_cond_wait(&cond, &mutex);
			//被唤醒的同时,尝试上锁
		}

		printf("%s\n", buf);

		flag = 1;
		//此时尝试唤醒另一个线程进行任务
		pthread_cond_signal(&cond);

		//解锁
		pthread_mutex_unlock(&mutex);
	}
	pthread_exit(NULL);
}

//线程执行体
void* CallBack_swap(void *arg)
{
	char temp = 0;
	int len = sizeof(buf);

	while(1)
	{
		/****************临界区******************/
		//上锁
		pthread_mutex_lock(&mutex);

		if(flag != 1)
		{
			pthread_cond_wait(&cond, &mutex);
		}

		for(int i=0; i<len/2; i++)
		{
			temp = buf[i];
			buf[i] = buf[len-i-2];
			buf[len-i-2] = temp;
		}
		flag = 0;

		pthread_cond_signal(&cond);

		pthread_mutex_unlock(&mutex);
	}
		pthread_exit(NULL);
}

//
int main(int argc, const char *argv[])
{

	pthread_t tid1, tid2;
	//创建两个新线程
	if(pthread_create(&tid1, NULL, CallBack_printf, NULL) != 0)
	{
		fprintf(stderr, "pthread_create have failed __%d__\n", __LINE__);
		return -1;
	}

	if(pthread_create(&tid2, NULL, CallBack_swap, NULL) != 0)
	{
		fprintf(stderr, "pthread_create have failed __%d__\n", __LINE__);
		return -1;
	}

	//对主线程进行阻塞
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);

	//摧毁互斥锁
	pthread_mutex_destroy(&mutex);

	//摧毁条件变量
	pthread_cond_destroy(&cond);


	return 0;
}

2.用条件变量实现,有编号为ABC的三个线程,线程内分别打印自己的线程编号,要求打印的顺序为ABC.

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem1, sem2, sem3;

void *CallBack_A(void *arg)
{
	while(1)
	{
		sem_wait(&sem1);
		printf("A");
		sem_post(&sem2);
	}
}
void *CallBack_B(void *arg)
{
	while(1)
	{
		sem_wait(&sem2);
		printf("B");
		sem_post(&sem3);
	}
}
void *CallBack_C(void *arg)
{
	while(1)
	{
		sem_wait(&sem3);
		printf("C\n");
		sem_post(&sem1);
	}
}

int main(int argc, const char *argv[])
{
	//创建两个信号量
	if(sem_init(&sem1, 0, 1) < 0)
	{
		perror("sem_init");
		return -1;
	}
	if(sem_init(&sem2, 0, 0) < 0)
	{
		perror("sem_init");
		return -1;
	}
	if(sem_init(&sem3, 0, 0) < 0)
	{
		perror("sem_init");
		return -1;
	}

	//创建ABC三个线程
	pthread_t tid1, tid2, tid3;
	if(pthread_create(&tid1, NULL, CallBack_A, NULL) < 0)
	{
		fprintf(stderr, "pthread_create failed\n");
		return -1;
	}
	if(pthread_create(&tid2, NULL, CallBack_B, NULL) < 0)
	{
		fprintf(stderr, "pthread_create failed\n");
		return -1;
	}
	if(pthread_create(&tid3, NULL, CallBack_C, NULL) < 0)
	{
		fprintf(stderr, "pthread_create failed\n");
		return -1;
	}

	//对主线程进程阻塞
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	pthread_join(tid3, NULL);

	//摧毁信号量
	sem_destroy(&sem1);
	sem_destroy(&sem2);
	sem_destroy(&sem3);


	return 0;
}

输出结果:

ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC

3.要求用信号量的方式实现,打印一次倒置一次。不允许使用flag

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>

//临界资源
char buf[] = "1234567";

//互斥锁的建立
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//创建条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

//信号量
sem_t sem; 	//用来上锁
sem_t sem1; 	//用来充当条件变量
//sem_t sem2;

//int flag = 0; 	//0:打印, 1:倒置

void* CallBack_printf(void *arg)
{
	while(1)
	{
		/******************临界区***************/
		//用信号量进行上锁 p操作
		sem_wait(&sem);

		printf("%s\n", buf);

		sem_post(&sem1);
	}
	pthread_exit(NULL);
}

//线程执行体
void* CallBack_swap(void *arg)
{
	char temp = 0;
	int len = sizeof(buf);

	while(1)
	{
		/****************临界区******************/
		//上锁

		sem_wait(&sem1);
		for(int i=0; i<len/2; i++)
		{
			temp = buf[i];
			buf[i] = buf[len-i-2];
			buf[len-i-2] = temp;
		}	
		sem_post(&sem);		

	}
		pthread_exit(NULL);
}

int main(int argc, const char *argv[])
{

	//创建一个信号量
	if(sem_init(&sem, 0, 1) < 0)
	{
		perror("sem_init");
		return -1;
	}
	if(sem_init(&sem1, 0, 0) < 0)
	{
		perror("sem_init");
		return -1;
	}
	//创建两个新线程
	pthread_t tid1, tid2;
	if(pthread_create(&tid1, NULL, CallBack_printf, NULL) != 0)
	{
		fprintf(stderr, "pthread_create have failed __%d__\n", __LINE__);
		return -1;
	}

	if(pthread_create(&tid2, NULL, CallBack_swap, NULL) != 0)
	{
		fprintf(stderr, "pthread_create have failed __%d__\n", __LINE__);
		return -1;
	}

	//对主线程进行阻塞
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);

// 	摧毁信号量
	sem_destroy(&sem);
	sem_destroy(&sem1);
		
	return 0;
}

输出结果:

1234567
7654321
1234567
7654321
1234567
7654321
1234567
7654321
1234567
7654321
1234567
7654321
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值