多线程

多线程是多任务处理的一种特殊形式,而多任务处理是一种让你的电脑能并发运行两个或两个以上程序的特性。一般有两种类型的多任务处理:基于进程的和基于线程的。

基于进程的多任务处理是并发执行的程序。基于线程的多任务处理是并发执行的程序的一部分。

多线程程序包含了可以并发运行的两个或更多个程序部分。这样程序中的每个部分称为一个线程,并且每个线程都定义了一个单独的执行路径。

C++ 不包含对多线程应用程序的任何嵌入式支持。相反,它完全依赖于操作系统来提供此项功能。

本教程假设您正在使用的是 Linux 操作系统,我们将要使用 POSIX 编写 C++ 多线程程序。 POSIX 线程,或称 Pthreads,它提供了在许多类 Unix 的 POSIX 系统(如 FreeBSD,NetBSD,GNU/Linux,Mac OS X 和 Solaris)中可用的 API。

创建线程

我们使用下面的函数来创建一个 POSIX 线程:

#include

pthread_create (thread, attr, start_routine, arg)

这里的 pthread_create 创建了一个新线程,并使其可执行。这个函数可以在代码中的任意位置调用任意次。

下面是详细的参数说明:

参数

描述

thread

新线程的不透明、唯一的标识符,它由子函数返回。

attr

一个不透明的属性对象,可用于设置线程属性。你可以指定一个线程的属性对象,默认值为 NULL。

start_routine

C++ 例程,线程一旦创建将会被执行。

arg

一个传递给 start_routine 的参数。它必须传递一个 void 类型指针的引用。如果没有参数传递,默认值为 NULL。

一个进程可创建的最大线程数是依赖实现决定的。线程一旦创建,它们之间是对等的,而且也有可能创建其它的线程。线程之间没有隐含的层次或依赖关系。

终止线程

我们使用下面的函数来终止一个 POSIX 线程:

#include

pthread_exit (status)

此处的 pthread_exit 用于显式的退出一个线程。通常在线程已完成了其工作,并且没有存在的必要的时候,调用 pthread_exit()函数。

如果 main()在其创建的线程之前终止,并且使用了 pthread_exit() 来退出线程,那么其线程将会继续执行。否则,当 main() 终止后,这些线程将会自动终止。

例子

下面简单的样例代码,用 pthread_create() 函数创建了 5 个线程。每个线程均打印 “Hello World!”,然后调用 pthread_exit() 函数终止了线程。

#include

#include

#include

using namespace std;

#define NUM_THREADS 5

void *PrintHello(void *threadid)

{

long tid;

tid = (long)threadid;

cout << "Hello World! Thread ID, " << tid << endl;

pthread_exit(NULL);

}

int main ()

{

pthread_t threads[NUM_THREADS];

int rc;

int i;

for( i=0; i < NUM_THREADS; i++ ){

cout << "main() : creating thread, " << i << endl;

rc = pthread_create(&threads[i], NULL,

PrintHello, (void *)i);

if (rc){

cout << "Error:unable to create thread," << rc << endl;

exit(-1);

}

}

pthread_exit(NULL);

}

使用 -lpthread 库编译上面的程序,如下所示:

$gcc test.cpp -lpthread

现在执行上面的程序,将会产生如下的结果:

main() : creating thread, 0

main() : creating thread, 1

main() : creating thread, 2

main() : creating thread, 3

main() : creating thread, 4

Hello World! Thread ID, 0

Hello World! Thread ID, 1

Hello World! Thread ID, 2

Hello World! Thread ID, 3

Hello World! Thread ID, 4

传递参数给线程

下面的例子展示了如何通过一个结构体传递多个参数。你可以在一个线程回调中传递任何数据类型,这是因为它指向 void 类型。

下面的例子解释了这一点:

#include

#include

#include

using namespace std;

#define NUM_THREADS 5

struct thread_data{

int thread_id;

char *message;

};

void *PrintHello(void *threadarg)

{

struct thread_data *my_data;

my_data = (struct thread_data *) threadarg;

cout << "Thread ID : " << my_data->thread_id ;

cout << " Message : " << my_data->message << endl;

pthread_exit(NULL);

}

int main ()

{

pthread_t threads[NUM_THREADS];

struct thread_data td[NUM_THREADS];

int rc;

int i;

for( i=0; i < NUM_THREADS; i++ ){

cout <

td[i].thread_id = i;

td[i].message = "This is message";

rc = pthread_create(&threads[i], NULL,

PrintHello, (void *)&td[i]);

if (rc){

cout << "Error:unable to create thread," << rc << endl;

exit(-1);

}

}

pthread_exit(NULL);

}

当上述代码编译和执行后,将会有以下的结果:

main() : creating thread, 0

main() : creating thread, 1

main() : creating thread, 2

main() : creating thread, 3

main() : creating thread, 4

Thread ID : 3 Message : This is message

Thread ID : 2 Message : This is message

Thread ID : 0 Message : This is message

Thread ID : 1 Message : This is message

Thread ID : 4 Message : This is message

连接和分离线程

下面的两个函数,我们可以用它们来连接或分离线程:

pthread_join (threadid, status)

pthread_detach (threadid)

pthread_join()子例程会阻塞调用它的线程,一直等到其指定的 threadid 的线程结束为止。当一个线程创建后,它的属性决定了它是否是可连接的或可分离的。只有创建时属性为可连接的线程才可以连接。如果创建的是一个可分离的线程,那么它永远不能连接。

下面的例子演示了如何使用 pthread_join 函数来等待一个线程结束。

#include

#include

#include

#include

using namespace std;

#define NUM_THREADS 5

void *wait(void *t)

{

int i;

long tid;

tid = (long)t;

sleep(1);

cout << "Sleeping in thread " << endl;

cout << "Thread with id : " << tid << " ...exiting " << endl;

pthread_exit(NULL);

}

int main ()

{

int rc;

int i;

pthread_t threads[NUM_THREADS];

pthread_attr_t attr;

void *status;

// Initialize and set thread joinable

pthread_attr_init(&attr);

pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

for( i=0; i < NUM_THREADS; i++ ){

cout << "main() : creating thread, " << i << endl;

rc = pthread_create(&threads[i], NULL, wait, &&i );

if (rc){

cout << "Error:unable to create thread," << rc << endl;

exit(-1);

}

}

// free attribute and wait for the other threads

pthread_attr_destroy(&attr);

for( i=0; i < NUM_THREADS; i++ ){

rc = pthread_join(threads[i], &status);

if (rc){

cout << "Error:unable to join," << rc << endl;

exit(-1);

}

cout << "Main: completed thread id :" << i ;

cout << " exiting with status :" << status << endl;

}

cout << "Main: program exiting." << endl;

pthread_exit(NULL);

}

当上述代码编译和执行后,将产生以下的结果:

main() : creating thread, 0

main() : creating thread, 1

main() : creating thread, 2

main() : creating thread, 3

main() : creating thread, 4

Sleeping in thread

Thread with id : 0 .... exiting

Sleeping in thread

Thread with id : 1 .... exiting

Sleeping in thread

Thread with id : 2 .... exiting

Sleeping in thread

Thread with id : 3 .... exiting

Sleeping in thread

Thread with id : 4 .... exiting

Main: completed thread id :0 exiting with status :0

Main: completed thread id :1 exiting with status :0

Main: completed thread id :2 exiting with status :0

Main: completed thread id :3 exiting with status :0

Main: completed thread id :4 exiting with status :0

Main: program exiting.

java多线程w3c_多线程相关推荐

  1. JAVA并发之多线程基础(2)

    除了我们经常用的synchronized关键字(结合Object的wait()和notify()使用)之外,还有对应的上篇文章讲到的方法JAVA并发之多线程基础(1)之外,我们日常中使用到最多的也就是 ...

  2. Java基础、多线程、JVM、集合八股文自述(持续更新)

    Java基础.多线程.JVM.集合八股文自述 一.Java基础 1.1 object类有哪些方法? getClass().hashCode().equals().clone().toString(). ...

  3. Java中的多线程编程(超详细总结)

    文章目录 Java中的多线程编程(超详细总结) 一.线程与多线程的概念 二.线程与进程之间的关系 三.一个线程的生命周期 四.多线程的目的和意义 五.线程的实现的方式 Java中的多线程编程(超详细总 ...

  4. Java回顾之多线程

    在这篇文章里,我们关注多线程.多线程是一个复杂的话题,包含了很多内容,这篇文章主要关注线程的基本属性.如何创建线程.线程的状态切换以及线程通信,我们把线程同步的话题留到下一篇文章中. 线程是操作系统运 ...

  5. Java基础之多线程详细分析

    在了解多线程之前,先来了解一下进程与线程之间的关系. 进程和线程: 进程是指在系统中正在执行的一个程序,每个进程之间是独立的. 线程是进程的一个基本执行单元.一个进程要想执行任务,必须得有线程(每1个 ...

  6. java.text.SimpleDateFormat多线程下的问题

    1. 今天在做性能压测的时候发现java.text.SimpleDateFormat多线程下的错误 2. 先贴出两段错误大家看一下: Exception in thread "pool-1- ...

  7. java面试题 多线程_Java面试常见关于多线程的面试题

    多线程是Java技术中常用而且相对比较难易理解的一个知识点.而且多线程也是企业实际应用中必备的技术,因此在面试的过程中,面试者经常被问到关于多线程的问题,遇到这些问题大家应该怎么办呢?赶紧恶补一下Ja ...

  8. JAVA并发之多线程基础(5)

    上面介绍了并发编程中的栅栏等JAVA并发之多线程基础(4) .通过唯一的一个终点线来帮助确定线程是多晚开始执行下一次操作. LockSupport 提供了一个比较底层的线程挂起操作.有点类似于susp ...

  9. JAVA中的多线程(一)

    JAVA中的多线程(一) 进程:是一个正在执行中的程序 每一个进程执行都有一个执行的顺序,该顺序是一个执行路径,或者叫控制单元 线程:就是进程中的一个独立的控制单元 线程在控制着进程的执行 一个进程中 ...

最新文章

  1. mongodb 3.2配置内存缓存大小为MB/MongoDB 3.x内存限制配置
  2. python使用缩进作为语法边界一般建议怎样缩进-Python基础自测挑战题
  3. Android 混淆打包
  4. Django--filter()-字段查找(双下划线的使用详解)
  5. python PyQt5 QSlider类(滑块)
  6. django 转发_教你搭建Django环境,就是这么简单
  7. 安装VSTFS后遗症解决方法
  8. 数据结构与算法-时间复杂度的级别-时间复杂度的算法
  9. TensorFlow 教程 --进阶指南--3.4数据读取
  10. 防止SQL注入的五种方法
  11. 第四周作业part1
  12. 转:最详细的JavaScript 教程,入门级都能看懂
  13. docker制作Nginx镜像
  14. 百度直达号,一场自high的喜剧
  15. 物联网连接拼图:蜂窝与非蜂窝
  16. 普通table表格样式大全
  17. ioctl函数详细说明(网络)
  18. API 接口设计规范
  19. 怎么看区块链正规项目与否,区块链投资前你应知道这三点
  20. 2020高级操作系统 复习考点(五)

热门文章

  1. 使用Pocsuite3
  2. linux日志本地存储和网络存储,文件系统和本地存储管理 1
  3. [Python从零到壹] 十三.机器学习之聚类算法四万字总结全网首发(K-Means、BIRCH、树状聚类、MeanShift)
  4. iOS之深入解析GCD的底层原理
  5. SwiftUI之深入解析高级动画的时间轴TimelineView
  6. 2015年第六届蓝桥杯 - 省赛 - Java大学B组 - A. 三角形面积
  7. YOLO_ Real-Time Object Detection 实时目标检测
  8. 科技公司预备持jiu战:谷歌将允许员工在2021年7月前居家办公
  9. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1095:数1的个数
  10. C语言中的各输出格式含义