线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。
线程是独立调度和分派的基本单位。线程可以为操作系统内核调度的内核线程,如Win32线程;由用户进程自行调度的用户线程,如Linux平台的POSIX Thread;或者由内核与用户进程,如Windows 7的线程,进行混合调度。
同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。
一个进程可以有很多线程,每条线程并行执行不同的任务。
在多核或多CPU,或支持Hyper-threading的CPU上使用多线程程序设计的好处是显而易见,即提高了程序的执行吞吐率。在单CPU单核的计算机上,使用多线程技术,也可以把进程中负责I/O处理、人机交互而常被阻塞的部分与密集计算的部分分开来执行,编写专门的workhorse线程执行密集计算,从而提高了程序的执行效率。
然后简单的理解就是一个进程相当于是我们的一整条流水线,进行一个完整的工作项目,然后每一个线程就是流水线上的一个个工人,分别进行着不同的任务,并且享有不同的资源和空间。
系统分配给进程也就是整条流水线资源,然后流水线也就是进程再把资源分配给线程。
线程就是最小的任务执行单位,线程构成一个大的进程(任务)
#include <windows.h>
#include <stdio.h>
#include<conio.h>
DWORD WINAPI ThreadFunc( LPVOID lpParam ) //线程函数,跟普通的函数没什么两样
{
printf( " 我是第%d个线程.", *(DWORD*)lpParam );
return 0;
}
int main( void )
{
DWORD dwThreadId, dwThrdParam = 1;
HANDLE hThread;
hThread = CreateThread( NULL,0,ThreadFunc,&dwThrdParam, 0,&dwThreadId);
if (hThread == NULL)
{
printf( "CreateThread failed (%d)\n", GetLastError() );
}
else
{
_getch();
CloseHandle( hThread );
}
}
DWORD 就是 Double Word, 每个word为2个字节的长度,DWORD 双字即为4个字节,每个字节是8位,共32位。
DWORD在Windows下经常用来保存地址(或者存放指针)。
这是DWORD的宏定义,使用时不需要定义,直接引用windows.h即可
#define DWORD unsigned long
HANDLE:句柄,是Windows用来表示对象的.在windows程序中,有各种各样的资源(,系统在创建这些资源时会为他们分配内存,并返回标示这些资源的标示号,即句柄 。
句柄指的是一个核心对象在某一个进程中的唯一索引,而不是指针。
由于地址空间的限制,句柄所标识的内容对进程是不可见的,只能由操作系统通过进程句柄列表来进行维护。句柄列表:每个进程都要创建一个句柄列表,这些句柄指向各种系统资源,比如信号量,线程,和文件等,进程中的所有线程都可以访问这些资源 。然后这里由于进程也是一个windows资源,所以需要句柄来访问这个进程。
HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId);
第一个参数 lpThreadAttributes 表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。
第二个参数 dwStackSize 表示线程栈空间大小。传入0表示使用默认大小(1MB)。
第三个参数 lpStartAddress 表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址,可以理解为这些线程属于同一个进程。然后我们这里的进程函数就是生成一个单一线程的函数。
第四个参数 lpParameter 是传给线程函数的参数。
第五个参数 dwCreationFlags 指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。
第六个参数 lpThreadId 将返回线程的ID号,传入NULL表示不需要返回该线程ID号。
函数如果返回0则创建失败
LPVOID 是一个没有类型的指针,因为这里是要传给我们的进程函数,由于用户使用不确定,所以就使用的是一个任意类型的指针
LPDWORD是指向dword类型的长指针,这里是用来储存我们线程的id号。
记着创造完线程要关闭线程