线程的那点事

刚刚写完一个简单的线程池,有很多需要总结的,好废话不多说,开整。
vc下新建一个win32位控制台工程:

int main()
{
   printf_s("HELLO WORLD\n");
}

单击F5编译,在控制台输出 HELLO WORLD ,这个过程就是一个进程从创建到结束的过程。进程的官方定义是:一定的资源和定义在上面的一系列操作,进程运行的过程就是资源的调用和分配的过程。

但实际上真正执行这个代码块的并不是进程,而是线程(每一个单线程都会自带一个主线程,你可以理解为main函数)。线程就是那个定义在资源上面的一系列操作。

线程和进程的关系有点像英国的君主立宪制,进程对象就是女王,线程对象就是内阁。女王是国家的象征,但是国家的运转还是要看内阁的,主线程对象就相当于首相,而线程的运行过程就相当于内阁的执政过程。

好现在让我们开始创建一个帝国(新建一个工程,引用一些常用的头文件):
vc下有自带的线程API 如果想要引用的话调用

...
#include<windows.h>
...

国家的基础已经有了,我们开始向里面填充框架,我们的女王和首相在创建工程的时候就已经有了,但是一个国家的政府机关仅仅有这两个人是不够的,我们要有小弟。。。。
我们先收一个小弟,他的名字叫做“hthread”。

//创建一个线程,hthread为线程句柄,我们大多数操作通过它来完成
HANDLE hthread = (HANDLE)malloc(sizeof(HANDLE));
hthread = CreateThread(NULL,0,function_thread,NULL,0,NULL);

直接扯过来MSDN中CreateThread():

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  SIZE_T dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  DWORD dwCreationFlags,
  LPDWORD lpThreadId
);

我们解释一下函数中的五个参数:
LPSECURITY_ATTRIBUTES lpThreadAttributes 这个是安全级别,也就是操作权限,NULL表示默认,职位不同权限也不一样;
SIZE_T dwStackSize 表示线程的调用线程栈的大小,以字节为单位,填入0则表示与第一个线程分配的线程栈尺寸相同,职位不同能调用的资源多少也不同;
LPTHREAD_START_ROUTINE lpStartAddress 这是线程函数的地址,就相当于执政方针。
LPVOID lpParameter 这是在线程创建的时候,传入到线程函数中的参数,就相当于上级给你分配的资源
DWORD dwCreationFlags 这是线程创建时的标志,为0的时候代表立即执行,就是上级给你分配的指令,是立即行动还是原地待命
LPDWORD lpThreadId 这是线程的ID,这就是任务编号

我们新收的这个叫hthread的小弟,他的权限是默认的,调用的线程栈与第一个线程相同,传入的参数为空,创建后立即执行,线程ID我们没有获取。
ps:这些参数的妙用我们后面再讲,先来一个简单的例子。。。
好,我们已经创建好一个小弟了,接下来我们要给小弟指定任务,他到底应该干什么。

//函数名与LPTHREAD_START_ROUTINE lpStartAddress 即CreateThread()第三个参数保持一致
DWORD WINAPI fun_thread(LPVOID parament)
{
    printf_s("女王万岁万万岁!\n");
    return 0;
}
...
#include<windows.h>
...
DWORD WINAPI fun_thread(LPVOID parament)
{
    printf_s("女王万岁万万岁!\n");
    return 0;
}

int main()
{
   HANDLE hthread = (HANDLE)malloc(sizeof(HANDLE));
   hthread = CreateThread(NULL,0,function_thread,NULL,0,NULL);
   system("pause");
   return 0;
}

点击F5运行:

女王万岁万万岁!
按下任意键继续... ...

ps:可能有人编译后发现,这两句话顺序是反的,不过莫慌,原因我们慢慢到来。

好了,现在我们的帝国已经有一位了一个小弟了,但这个小弟貌似除了歌功颂德外没有别的用处,我们还要找几个干实事的。
依法炮制我们再创建两个小弟“奔波耳霸”和“霸波耳奔”

HANDLE baboeben = CreateThread(NULL,0,bbeb_thread,NULL,0,NULL);
HANDLE benboeba = CreateThread(NULL,0,bbeb_thread,NULL,0,NULL);

给他们俩分配任务:

DWORD WINAPI bbeb(LPVOID parament)
{
    while(1)
    {
         printf_s("臣%x有本要奏!\n",GetCurruntThread());
         //GetCurruntThread(),获取当前线程的句柄,返回一个HANDLE
         //类型的值 HANDLE实际是一个void *指针
    }
    return 0;
}
...
#include<windows.h>
...
DWORD WINAPI fun_thread(LPVOID parament)
{
    printf_s("女王万岁万万岁!\n");
    return 0;
}

DWORD WINAPI bbeb(LPVOID parament)
{
    while(1)
    {
         printf_s("臣%x有本要奏!\n",GetCurruntThread());
         //GetCurruntThread(),获取当前线程的句柄,返回一个HANDLE
         //类型的值 HANDLE实际是一个void *指针
    }
    return 0;
}

int main()
{
   HANDLE hthread = (HANDLE)malloc(sizeof(HANDLE));
   hthread = CreateThread(NULL,0,function_thread,NULL,0,NULL);
   HANDLE baboeben = CreateThread(NULL,0,bbeb_thread,NULL,0,NULL);
   HANDLE benboeba = CreateThread(NULL,0,bbeb_thread,NULL,0,NULL);
   system("pause");
   return 0;
}

好了,我们又收了两个小弟,一个奔波耳霸一个霸波耳奔,按下F5键运行
运行后我们会发现控制台里面不停的重复播出同一句话: 臣XXXX有本要奏。
这时候你可能心里很不爽,因为只有一个小弟在做事啊,另一个小弟完全不作为啊。于是你默默的重新编译,发现结果相同,不过有一个神奇的事情就是那一句很不和谐的:按下任意键继续… …出现的位置是随即的。
这个事情上面就发生过了,这难道是灵异事件??程序执行的时候不是逐句按顺序执行的吗??system(“pause”)在线程创建的后面,而执行的时候在线程的前面??
这个问题,其实很简单。。。

不过我们还是要先解决一下奔波耳霸和霸波耳奔的问题,两个人只有一个人一直在叨比叨另一个一句话都不说,其实另一个不是不想说,而是完全插不上嘴,前一个人一直在那说个不停。
解决这个问题见下一回。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值