多线程练习1

第一题:

使用多线程完成两个文件的拷贝,分支线程1,拷贝前一半,分支线程2拷贝后一半,主线程用于回收分支线程的资源

实现代码:

typedef struct{
	int start;//读取开始位置
	int len;//读多少
	char src[20];
	char dest[20];
}param_t;

void* task(void* argv){
	param_t *p=(param_t*)argv;	
	printf("线程[%#lX]拷贝[%d][%d]\n",pthread_self(),p->start,p->len);

	int src=open(p->src,O_RDONLY);
	int dest=open(p->dest,O_WRONLY);
	
	lseek(src,p->start,SEEK_SET);
	lseek(dest,p->start,SEEK_SET);

	char buf[128];
	int i;
	for(i=0;i+sizeof(buf) < p->len;i+=sizeof(buf)){
		ssize_t cnt=read(src,buf,sizeof(buf));
		write(dest,buf,cnt);
	}
	ssize_t cnt=read(src,buf,p->len-i);
	write(dest,buf,cnt);

	close(src);
	close(dest);

	pthread_exit(NULL);
}

int getFileSize(const char* path){
	int fd=open(path, O_RDONLY);
	if(fd == -1){
		perror("源文件打开失败");
		return -1;
	}
	int size=lseek(fd,0,SEEK_END)-lseek(fd,0,SEEK_SET);
	close(fd);
	return size;
}

int createFile(const char* path){
	int fd=open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
	if(fd == -1){
		perror("目标文件打开失败");
		return -1;
	}
	close(fd);
	return 0;
}

int main(int argc, const char *argv[])
{
	//读取源文件的大小
	int size=getFileSize(argv[1]);	
	if(size == -1)
		return -1;
	//创建目标文件
	if(createFile(argv[2]) == -1)
		return -1;
	
	//调用子线程
	pthread_t t1,t2;
	param_t p1={0, size/2};
	strcpy(p1.src, argv[1]);
	strcpy(p1.dest, argv[2]);
	//
	param_t p2={size/2,size-size/2};
	strcpy(p2.src, argv[1]);
	strcpy(p2.dest, argv[2]);
	pthread_create(&t1,NULL,task,&p1);
	pthread_create(&t2,NULL,task,&p2);

	pthread_join(t1, NULL);
	pthread_join(t2, NULL);
	printf("文件拷贝完成\n");
	
	return 0;
}

运行效果:

ubuntu@ubuntu:~/99-Prac/1018$ ./a.out passwd 1.txt
线程[0X7F0657FBB6C0]拷贝[0][1491]
线程[0X7F06577BA6C0]拷贝[1491][1491]
文件拷贝完成
ubuntu@ubuntu:~/99-Prac/1018$ diff passwd 1.txt

第二题:互斥锁的练习 mutex

互斥锁练习。引用书《Linux_C编程一站式学习》

编写两个线程,并发执行每个线程计数5000下,总共执行10000

1、无互斥锁代码

int count=0;

void* task(void* argv){
	int val;
	for(int i=0;i<5000;i++){
		//编写更多的费代码,给线程间切换留出更多机会
		val=count;
		printf("线程[%#lX],计数[%d]\n", pthread_self(),val+1);
		count=val+1;
	}

	pthread_exit(NULL);
}


int main(int argc, const char *argv[])
{
	pthread_t t1,t2;
	pthread_create(&t1,NULL,task,NULL);
	pthread_create(&t2,NULL,task,NULL);
	
	pthread_join(t1, NULL);
	pthread_join(t2, NULL);

	return 0;
}

2、无互斥锁运行结果

大多数的运行结果,在5000左右,而目标是10000。

3、添加互斥锁

int count=0;
pthread_mutex_t mutex;//互斥锁

void* task(void* argv){
	int val;
	for(int i=0;i<5000;i++){
		//编写更多的费代码,给线程间切换留出更多机会
		pthread_mutex_lock(&mutex);
		val=count;
		printf("线程[%#lX],计数[%d]\n", pthread_self(),val+1);
		count=val+1;
		pthread_mutex_unlock(&mutex);
	}

	pthread_exit(NULL);
}


int main(int argc, const char *argv[])
{
	pthread_mutex_init(&mutex, NULL);

	pthread_t t1,t2;
	pthread_create(&t1,NULL,task,NULL);
	pthread_create(&t2,NULL,task,NULL);
	
	pthread_join(t1, NULL);
	pthread_join(t2, NULL);

	pthread_mutex_destroy(&mutex);

	return 0;
}

4、添加互斥锁后的运行结果

10000!


第三题:信号量的练习 semaphore

线程1:生产者,每5秒生产一个产品,初始化系统有5个产品。

线程2:消费者,随机3秒内消费一个产品。

生产者-消费者模型,若无产品了,消费者需要等到生产者再进行消费。

实现代码:

sem_t sem;//信号量
int num;//库存产品的剩余数据

void getCurrentTime(char* timeStr){
	time_t l=time(NULL);
	struct tm* t=localtime(&l);
	sprintf(timeStr,"%4d-%02d-%02d %02d:%02d:%02d",t->tm_year+1900,
			t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
}

//生产者任务
void* task1(void* argv){
	while(1){
		num++;
		sem_post(&sem);
		char timeStr[20];
		getCurrentTime(timeStr);
		printf("%s 生产者:生产了1个产品,库存[%d]个\n", timeStr, num);
		sleep(5);

	}
	pthread_exit(NULL);
}

//消费者任务
void* task2(void* argv){
	while(1){
		long t1=time(NULL);
		sem_wait(&sem);
		long t2=time(NULL);
		num--;
		char timeStr[20];
		getCurrentTime(timeStr);
		printf("%s 消费者:消费了1个产品,库存[%d]个.消费者等待了[%ld]秒\n", 
				timeStr, num,t2-t1);
		sleep(rand()%4);
	}
	pthread_exit(NULL);
}

int main(int argc, const char *argv[])
{
	sem_init(&sem, 0, 5);
	num=5;

	pthread_t t1,t2;
	pthread_create(&t1,NULL,task1,NULL);
	pthread_create(&t2,NULL,task2,NULL);


	pthread_join(t1, NULL);
	pthread_join(t2, NULL);

	sem_destroy(&sem);
		
	return 0;
}

运行效果:

ubuntu@ubuntu:~/99-Prac/1018$ ./a.out 
2024-10-18 21:02:31 生产者:生产了1个产品,库存[5]个
2024-10-18 21:02:31 消费者:消费了1个产品,库存[5]个.消费者等待了[0]秒
2024-10-18 21:02:34 消费者:消费了1个产品,库存[4]个.消费者等待了[0]秒
2024-10-18 21:02:36 生产者:生产了1个产品,库存[5]个
2024-10-18 21:02:36 消费者:消费了1个产品,库存[4]个.消费者等待了[0]秒
2024-10-18 21:02:37 消费者:消费了1个产品,库存[3]个.消费者等待了[0]秒
2024-10-18 21:02:40 消费者:消费了1个产品,库存[2]个.消费者等待了[0]秒
2024-10-18 21:02:41 生产者:生产了1个产品,库存[3]个
2024-10-18 21:02:41 消费者:消费了1个产品,库存[2]个.消费者等待了[0]秒
2024-10-18 21:02:44 消费者:消费了1个产品,库存[1]个.消费者等待了[0]秒
2024-10-18 21:02:46 生产者:生产了1个产品,库存[2]个
2024-10-18 21:02:46 消费者:消费了1个产品,库存[1]个.消费者等待了[0]秒
2024-10-18 21:02:46 消费者:消费了1个产品,库存[0]个.消费者等待了[0]秒
2024-10-18 21:02:51 生产者:生产了1个产品,库存[1]个
2024-10-18 21:02:51 消费者:消费了1个产品,库存[0]个.消费者等待了[4]秒
2024-10-18 21:02:56 生产者:生产了1个产品,库存[0]个
2024-10-18 21:02:56 消费者:消费了1个产品,库存[0]个.消费者等待了[4]秒
2024-10-18 21:03:01 生产者:生产了1个产品,库存[0]个
2024-10-18 21:03:01 消费者:消费了1个产品,库存[0]个.消费者等待了[3]秒
2024-10-18 21:03:06 生产者:生产了1个产品,库存[0]个
2024-10-18 21:03:06 消费者:消费了1个产品,库存[0]个.消费者等待了[2]秒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值