在早期的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;
}