多线程小结1

在早期的linux中,只有进程,没有线程。
进程是一个可执行程序的实体,由私有虚拟地址空间、代码、数据和其他操作系统资源(如进程创建的文件、管道、同步对象等)组成。此时的进程即是资源的拥有者,也是CPU的调度单位。
进程之间即可相互独立,又可相互协作完成并发任务。
但是多进程的协作有以下缺点:创建、销毁、切换速度慢,内存、资源占用大。
在对OS性能要求越来越高(大量数据接入、需要快速响应)的情况下,衍生了多线程。线程将原进程中的调度部分分离出来,成为CPU的调度实体,此时“进程是线程的容器”.应用程序可以有一个或多个进程,一个进程可以有一个或多个线程,其中一个是主线程。每个进程都至少拥有一个线程(主线程),多线程共享进程资源.
多线程的优点恰是多进程的缺点:创建、销毁、切换速度快,内存、资源占用小。
多线程虽好,但也有它自己的弊端:由于资源共享,对于独一份的资源,线程之间容易形成抢夺“冲突”。如果冲突处理不好,要么效率低下,要么形成死锁。
由此可见,多线程与多进程之间各有利弊,运用适当效率大大提升,反之会弄巧成拙。
多进程VS多线程
1)需要频繁创建销毁的优先用线程
2)需要进行大量计算的优先使用线程
3)强相关的处理用线程,弱相关的处理用进程
4)可能要扩展到多机分布的用进程,多核分布的用线程


下面这个例子有3个线程,完成2个任务,读写二进制文件和字符文件。
线程1,2读写同一个二进制文件,由于互斥等待,反而比一个线程用的时间更长。
线程3单独读写字符文件。

编译g++ -g -o thread Multiythread_example.cpp -lpthread

#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

#define DEBUG_THREAD

pthread_t thread[3];
pthread_mutex_t mut;

int  size_b;
int  global_v=0; 
char str[1024];
char buffer[1024];
FILE *f_out,*f_out2, *f_in,*f_in2;

void readWrite_binFile()
{
    global_v++;	
	
	if(f_in == NULL || f_out == NULL)
	{
		printf("can't open the source file.\n");
		return ;
	}
		
	while((size_b= fread(buffer,1,1024,f_out))>0)
    {
	  pthread_mutex_lock(&mut);//互斥
      fwrite(buffer,1,size_b,f_in);
	  pthread_mutex_unlock(&mut);
    }
}

void readWrite_characterFile()
{
    global_v++;
		
	if(f_in2 == NULL || f_out2 == NULL)
	{
		printf("can't open the source file.\n");
		return ;
	}

	while(!feof(f_out2))
	{
		fgets(str, 1024, f_out2);
		fputs(str, f_in2);
	}	
}

void *thread1(void*)
{
	printf("thread1 : I'm thread 1\n");
	printf("thread1 read and write bin file ! \n");	
	readWrite_binFile();
	printf("thread1 variable global_v = %d \n", global_v);	
	printf("thread1 :主函数在等我完成任务吗?\n");
	pthread_exit(NULL);
}
//线程1,2读写同一个文件
void *thread2(void*)
{
    //exit(1);如果一个线程退出,整个进程将退出
	printf("thread2 : I'm thread 2\n");
	printf("thread2 read and write char file ! \n");	
	readWrite_binFile();
	printf("thread2 variable global_v = %d \n", global_v);
	printf("thread2 :主函数在等我完成任务吗?\n");
	pthread_exit(NULL);
}

void *thread3(void*)
{
	printf("thread3 : I'm thread 3 \n");
	printf("thread3 read and write file ! \n");
	readWrite_characterFile();
	printf("thread3  variable global_v = %d \n", global_v);
	printf("thread3 :主函数在等我完成任务吗?\n");
	pthread_exit(NULL);
}

void thread_create(void)
{
	int temp;
	memset(&thread, 0, sizeof(thread));          
	//创建线程
	if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)       
		printf("线程1创建失败!\n");
	else
		printf("线程1被创建\n");

	if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0)  
		printf("线程2创建失败");
	else
		printf("线程2被创建\n");
		
	if((temp = pthread_create(&thread[2], NULL, thread3, NULL)) != 0)  
		printf("线程3创建失败");
	else
		printf("线程3被创建\n");
	
}

void thread_wait(void)
{
	//等待线程结束
	if(thread[0] !=0) 
	{                   
		pthread_join(thread[0],NULL);
		printf("线程1已经结束\n");
	}
	
	if(thread[1] !=0) 
	{                
		pthread_join(thread[1],NULL);
		printf("线程2已经结束\n");
	}

	if(thread[2] !=0) 
	{                
		pthread_join(thread[2],NULL);
		printf("线程3已经结束\n");
	}

}

int main()
{

    timeval tv, tv2;  
    long long L1, L2;
	 
	//用默认属性初始化互斥锁
	pthread_mutex_init(&mut,NULL);

	f_out = fopen("source.rar","r+");
	f_out2 = fopen("source.txt","r+");	
	f_in = fopen( "dest.rar","w+");
	f_in2 = fopen( "dest.txt","w+");
	

	gettimeofday(&tv, NULL);
    L1 = tv.tv_sec*1000*1000+tv.tv_usec;

	printf("我是主函数哦,我正在创建线程,呵呵\n");
	thread_create();
      	
	printf("我是主函数哦,我正在等待线程完成任务阿,呵呵\n");
	thread_wait();
	
	gettimeofday(&tv2, NULL);
	L2 = tv2.tv_sec*1000*1000+tv2.tv_usec;	
	
	#ifdef DEBUG_THREAD 
	printf("%lld\n",L2-L1);
	#endif
	
	fclose(f_out);
	fclose(f_in);
	fclose(f_out2);
	fclose(f_in2);
	
	return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值