C/C++基于线程的并发编程(一):初识线程编程
什么是线程
线程就是运行在进程上下文中的单元。进程是由多个线程组成,最简单的进程由一个线程组成,而这个线程就叫做主线程。线程由内核自动调度。每个线程都有自己的线程上下文,包括一个唯一的线程ID、栈、栈指针、程序计数器、通用目的寄存器和条件码。 由于多线程编程均在同一进程中,所以线程之间共享这个进程虚拟地址空间的所有内容,包括它的代码、数据、堆、共享库和打开文件等。这也是的线程的并发编程的引发安全性问题的原因,后续会对线程安全进行展开阐述。 如上图所示,进程开始生命周期时都是单一线程,而这个线程称为主线程。在某一个时刻,主线程创建一个对等线程,从这个时刻开始,两个线程就并发的运行。主线程执行延迟调用时,如read或者sleep操作,或者因为被内核的定时器中断,就会通过上下文切换传递到对等线程。而对等线程执行一段时间,再传递回主线程,依次类推。 线程的执行不同于进程,因为线程的上下文比进程的上下文小得多,所以线程上下文的效率要比进程的上下文切换快得多。另外,线程不像进程那样,不是按照严格的父子层次来组织的。主线程和其他线程的区别仅在于它总是进程第一个运行的线程。
多线程编程
介绍完线程的一些基础知识,下面用C和C++分别实现多线程编程。
C++的多线程编程
#include <iostream> #include <thread> using namespace std; void func() { for(int i = 0; i < 5; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); cout << "thread id:" << this_thread::get_id() << " run func" << endl; } } int main() { cout << "mainthread id: " << this_thread::get_id() << endl; std::thread t1 = std::thread(func); // 申请线程并在线程中运行func函数 std::thread t2 = std::thread(func); // 申请线程并在线程中运行func函数 t1.join(); // 等待t1线程结束 t2.join(); // 等待t2线程结束 return 0; }
以下程序的输出如下:
mainthread id: 1 thread id:2 run func thread id:3 run func thread id:2 run func thread id:3 run func thread id:2 run func thread id:3 run func thread id:2 run func thread id:3 run func thread id:2 run func thread id:3 run func
主线程的线程id为1,当线程对象申请开始,线程就已经开始执行func函数。id为2的线程和id为3的线程每隔500ms进行输出。而join函数的调用,会让主线程等待子线程运行结束后在进行退出。
C的多线程编程
#include <stdio.h> #include <pthread.h> #include <unistd.h> void* func(void *val) { for(int i = 0; i < 5; ++i) { usleep(500 * 1000); printf("thread id: 0x%x, run func ", (unsigned int)pthread_self()); } return NULL; } int main() { printf("mainthread id: 0x%x ", (unsigned int)pthread_self()); pthread_t t1; pthread_t t2; pthread_create(&t1, NULL, func, NULL); // 创建线程 pthread_create(&t2, NULL, func, NULL); // 创建线程 pthread_join(t1, NULL); // 等待t1线程结束 pthread_join(t2, NULL); // 等待t1线程结束 return 0; }
以下程序的输出如下:
mainthread id: 0xf7da0740 thread id: 0xf7d9f700, run func thread id: 0xf759e700, run func thread id: 0xf7d9f700, run func thread id: 0xf759e700, run func thread id: 0xf7d9f700, run func thread id: 0xf759e700, run func thread id: 0xf759e700, run func thread id: 0xf7d9f700, run func thread id: 0xf7d9f700, run func thread id: 0xf759e700, run func
输出效果和C++实现类似,两个线程交替调用func函数。该环境跑在linux。
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
Node.js升级或降低版本