线程
线程即进程中执行运算的最小单位,亦即执行处理机调度的基本单位。如果把进程理解为在逻辑上操作系统锁完成的任务,那么线程表示完成该任务的许多可能的子任务之一。线程可以在处理器上独立调度执行,这样,在多处理器环境下就可以运行多个线程各自在单独处理器上进行。线程的好处有:
1.易于调度,线程是系统调度的基本单位,线程的切换比进程要快
2.提高并发性,通过线程壳方便有效地实现并发性,进程壳创建多个线程来指向同一程序的不同部分
3.开销少,创建线程比创建进程快,仅占用少量资源比如栈与寄存器
4.利于充分发挥多处理器的功能,创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行
线程与进程
1.一个线程只能属于一个进程,而一个进程可以有多个线程但至少有一个线程
2.进程事拥有资源的基本单位,同一进程的所有线程贡献该进程的所有资源
3.线程拥有CPU,即在CPU上运行的是线程,运行一定时间片就会被切换
4.线程在运行过程中,需要同步与互斥,不同进程的线程间要利用进程通信的办法实现同步
5.线程是系统调度的基本单位,进程事拥有资源的基本单位,线程除了拥有部分寄存器和栈外,不拥有系统资源,但可以访问隶属于进程的资源
如何创建一个线程
多线程编程包含三个组成部分:
1.线程执行函数 新线程中要执行的代码
2.线程创建函数 负责新线程的创建
3.线程数据同步机制 负责多线程执行环境条件下数据的完整性和一致性
用CreateThread创建线程,windows的API,不调用MFC和RTL函数时,可以用CreateThread,其他情况不要用:
1 C Runtime中需要对多线程进行记录和初始化,保证C函数库工作正常
2 MFC也需要对新线程的创建做一些初始化工作,分配一些内存
3 有些CRT函数,比如malloc(),fopen()等,需要专门的线程存储数据块,这个数据块通常在创建线程时建立,如果使用CreateThread,这个数据块就没有建立,因此函数会自己创建一个,但是这样的话,函数不会把这块内存删除,于是在线程频繁启动的软件中1,这样会让系统的内存资源被耗尽。
工作者线程,MFC中不能用,C Runtime中不能用,任何时候最好都不用
#include<Windows.h>
#include<process.h>
#include<stdio.h>
int g_iValue = 0;
DWORD _stdcall ThreadProc(void* arg) {
for (int i = 0;i < 5;i++) {
g_iValue++;
printf("g_iValue = %d\n", g_iValue);
}
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
hArray[0] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
hArray[1] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
return 0;
}
用_beginthreadex创建线程 MS对C Runtime库的扩展SDK函数,首先针对C Runtime做了一些初始化的工作,保证C Runtime库工作正常,然后再调用CreateThread创建线程 调用了C运行库,但不能用在MFC中
#include<Windows.h>
#include<process.h>
#include<stdio.h>
int g_iValue = 0;
UINT _stdcall ThreadProc(LPVOID arg) {
for (int i = 0;i < 5;i++) {
g_iValue++;
printf("g_iValue = %d\n", g_iValue);
}
return 1;
}
int main(int argc, char* argv[])
{
HANDLE hArray[2] = { 0 };
unsigned tid = 0;
hArray[0] = (HANDLE)_beginthreadex(NULL, 0,ThreadProc,NULL,0,&tid);
hArray[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, &tid);
WaitForMultipleObjects(2, hArray, TRUE, INFINITE);
CloseHandle(hArray[0]);
CloseHandle(hArray[1]);
return 0;
}
AfxBeginThread MFC中线程创建的MFC函数,首先创建了相应的C WinThread对象,然后调用C WinTread::CreateThread,在C WinThread::CreateThread中,完成了对线程对象的初始化工作,然后再调用_beginthreadex创建线程。 在MFC中使用,工作者线程/界面线程
pthread_create LINUX平台