C语言 多线程使用说明1-创建线程

本文基于本校计算机学院的教程和自己的体会改编,并不是特别的干货,不过适合新人入门看看:

首先得知道什么是进程什么是线程?(水,非干货)

一个通俗的解释是,进程是指在系统中正在运行的一个应用程序;程序一旦运行就是进程,或者更专业化来说:进程是指程序执行时的一个实例。线程是进程的一个实体。进程——资源分配的最小单位,线程——程序执行的最小单位。

在我们学校的教材中,进程通常被定义为一个正在运行的程序的实例,是动态的。如果把程序比作菜谱,那么进程就是按照菜谱做菜的过程,当运行一个可执行程序就启动了该程序的一个实例,即创建了一个进程。当我此时正在补这一篇csdn的时候,电脑放着歌,TIM也在闪动,我也在向这个网站上输入文字,一台机器可以同时进行着多个进程,这就是进程的并发特征。他们其实看起来是在同时进行,实则是轮流使用着CPU的时间片的,只是因为时间片很短,所以用户感受不到这种变换。

进程具有并发性,那么有没有可能在一个程序内部,也可以有多个任务并发独立执行呢?

那系当然的啦~使用线程可以达到目的。线程是进程内部的一个执行单元。每一个进程至少有一个这样的执行单元,称之为主线程,它无需由用户去主动创建而是系统主动创建的。主线程终止,则该进程也随之终止。在C语言中,主线程的执行代码入口就是main函数。当然用户可以根据需要在主线程执行过程中创建其他线程,多个线程并发的存在于一个进程中。比如在bupt的电梯一楼,你可以按下“上”的同时,看到显示屏上实时输出电梯的运行状态的变化。

多线程可以并发的运行在同一个进程之中,实现并行处理,避免某项任务长时间占用CPU时间,因此多线程技术的应用也非常广泛。

如果需要多个任务并发执行,因此肯定需要用到线程,那么如何在我们的程序中创建线程呢?(水,非干货)

创建线程可以使用Windows操作系统提供的API函数CreateThread来完成,该函数将会创建一个线程并且返回已建线程的句柄(英文叫做handle)。

该函数的原型声明如下描述:

HANDLE CreateThread(LPSECURRY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags,

LPDWORD lpThreadid)

其中,lpThreadAttributes指向一个SECURITY_ATTRIBUTES结构的指针,该结构决定了线程的安全属性,一般置为NULL;

dwStackSize:设置线程初始栈的大小,即线程可以将多少地址空间用于自身的栈区,一般都默认为0,表示用多少要多少。

lpStartAddress:新线程开始执行时代码所在函数的地址,即线程的起始地址

lpParameter:制定了线程执行时传给线程的参数

dwCreationFlags:控制线程创建的附加标志,有两种取值。0:创建后提及执行;CREATE_SUSPENDED,则线程创建后处于挂起状态并不马上执行,直至函数ResumeThread被调用。

lpThreadId:接受线程ID,不感兴趣弄成NULL就是了。

比如下面:

#include <stdio.h>

#include<windows.h>

DWORD WINAPI Fun(LPVOID lpParameter);

int main()

{

HANDLE hThread1;//<1>

hThread1=CreateThread(NULL,0,Fun,NULL,0,NULL); //<2>

CloseHandle(hThread1);//<3>

printf("Damn,main thread is running\n");  //<4>

return 0;

}

DWORD WINAPI Fun(LPVOID lpParameter)

{

printf("yes,sir,Fun thread is running\n");

return 0;

}

运行出来就是damn,main thread is running

解释一下:

1.包含windows.h(要用到win的api)

2.线程函数就意思意思一下

3.main作为主线程,可以在其中创建新的线程,首先调用CreateThread创建一个新的线程,第一个参数设成NULL表示默认安全性,第二个参数为0表示调用默认的栈区空间(需要多少拿多少,和下载游戏时候的设置一样的),第三个参数是指定线程的入口函数的接口;第四个参数是传递给线程1的参数,这里不需要,所以写成NULL,第五个是希望线程一旦创建就开始执行而不是suspended;最后一个参数是用于指向线程id的变量,因为这里不需要id信息,也设置成NULL。

4.创建线程完毕之后,调用Close Handle函数关闭新线程的句柄。刚刚创建了线程,为啥又把他关闭呢?实际上,Close Handle函数并没有终止新创建的线程,只是表示在主线程中对新建的线程句柄不是很感兴趣而已,因此把他关了。

5.那么为什么要关闭线程的句柄呢?线程的内核对象有一个引用计数器,该计数器初始值是一,当创建线程计数器+1,当关闭线程句柄或者线程执行完毕之后,计数器-1.当线程引用计数器为0时候,系统就会释放线程内核对象。记住当如果不再需要线程句柄的时候应该把他关了就行

6.为什么最后只有主线程那句话运行了呢?这个问题请见我下一篇线程水文。

猜你喜欢

转载自blog.csdn.net/qq_42229034/article/details/81811494