多线程

多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。[1] 在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理(Multithreading)”。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程(台湾译作“执行绪”),进而提升整体处理性能。

// ConsoleApplication3.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


#include "stdio.h"
#include "stdlib.h"
#include "process.h"
#include "Windows.h"
typedef struct HE *H;
struct HE {
    int x;
    int y;
};

void run(void *p)
{
    int *px = (int*)p;
    char str[100] = { 0 };
    sprintf_s(str, "线程%d启动", *px);
    MessageBoxA(0, str, "hello", 0);
}

int main()
{
    H t = (H)malloc(sizeof(struct HE));
    t->x = 3;
    t->y = 4;
    printf("%d", t->x);
    MessageBoxA(0, "qwe", "ASD", 0);
    for (int i = 0; i<5; i++)
    {
        //run(&i);  //单线程
        _beginthread(run, 0, &i);   //多线程
        Sleep(10);
    }
    system("pause");
    return 0;
}

一个简单的使用_beginthread创建线程的例子。所在头文件为"process.h"

_beginthead的函数原型为:_beginthread(void(_cdecl *start_address) (void*), unsigned stack_size, void* arglist);

参数分别为:函数的入口地址,栈大小, 参数列表。

根据函数原型的第一个参数,可知,线程函数的语法如下:

void _cdecl ThreadFunc(void * param){}

//用_beginthread 创建线程  
//注:对应的线程函数的语法为  
// void _cdecl ThreadProc(void* pParam);   

#include <iostream>  
#include <process.h>  
#include <windows.h>  

using namespace std;  

void ThreadFun1(PVOID param){  
    while (1){  
        Sleep(1000);  
        cout << "this is ThreadFun1" << endl;  
    }  
}  

void  ThreadFun2(PVOID param){  
    while (1){  
        Sleep(1000);  
        cout << "this is ThreadFun2" << endl;  
    }  
}  

int main(){  
    int i = 0;  

    _beginthread(ThreadFun1, 0, NULL);  
    _beginthread(ThreadFun2, 0, NULL);  
    Sleep(30000);  
    cout << "end" << endl;  
    return 0;  
}  

1。单进程单线程:一个人在一个桌子上吃菜。
2。单进程多线程:多个人在同一个桌子上一起吃菜。
3。多进程单线程:多个人每个人在自己的桌子上吃菜。
多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。。。此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。
1。对于 Windows 系统来说,【开桌子】的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜。因此 Windows 多线程学习重点是要大量面对资源争抢与同步方面的问题。
2。对于 Linux 系统来说,【开桌子】的开销很小,因此 Linux 鼓励大家尽量每个人都开自己的桌子吃菜。这带来新的问题是:坐在两张不同的桌子上,说话不方便。因此,Linux 下的学习重点大家要学习进程间通讯的方法。
开桌子的意思是指创建进程。开销这里主要指的是时间开销。
可以做个实验:创建一个进程,在进程中往内存写若干数据,然后读出该数据,然后退出。此过程重复 1000 次,相当于创建/销毁进程 1000 次。在我机器上的测试结果是:
UbuntuLinux:耗时 0.8 秒
两者开销大约相差一百倍。这意味着,在 Windows 中,进程创建的开销不容忽视。换句话说就是,Windows 编程中不建议你创建进程,如果你的程序架构需要大量创建进程,那么最好是切换到 Linux 系统。
大量创建进程的典型例子有两个,一个是 gnu autotools 工具链,用于编译很多开源代码的,他们在 Windows 下编译速度会很慢,因此软件开发人员最好是避免使用 Windows。另一个是服务器,某些服务器框架依靠大量创建进程来干活,甚至是对每个用户请求就创建一个进程,这些服务器在 Windows 下运行的效率就会很差。这”可能”也是放眼全世界范围,Linux 服务器远远多于 Windows 服务器的原因。

如果你是写服务器端应用的,其实在现在的网络服务模型下,开桌子的开销是可以忽略不计的,因为现在一般流行的是按照 CPU 核心数量开进程或者线程,开完之后在数量上一直保持,进程与线程内部使用协程或者异步通信来处理多个并发连接,因而开进程与开线程的开销可以忽略了。
另外一种新的开销被提上日程:核心切换开销。
现代的体系,一般 CPU 会有多个核心,而多个核心可以同时运行多个不同的线程或者进程。
当每个 CPU 核心运行一个进程的时候,由于每个进程的资源都独立,所以 CPU 核心之间切换的时候无需考虑上下文。
当每个 CPU 核心运行一个线程的时候,由于每个线程需要共享资源,所以这些资源必须从 CPU 的一个核心被复制到另外一个核心,才能继续运算,这占用了额外的开销。
换句话说,在 CPU 为多核的情况下,多线程在性能上不如多进程。因而,当前面向多核的服务器端编程中,需要习惯多进程而非多线程。

部分内容来源于 https://www.zhihu.com/question/19901763/answer/13299543
作者:pansz

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值