pthread 多线程介绍

首先通过一个简单的故事让大家了解什么是线程模型?
有兄弟三人开车出去自驾游, 旅途非常遥远,需要好几天的车程。所以需要三个人轮流开车,这个时候可以一个人开车另外两个人可以去睡觉了,这样大家轮流开车。当开车司机想睡觉的时候可以通过轻轻推醒一个人来接替开车另一个仍然可以接着睡,如果开车司机不高兴也可以通过大声说话的方式,将两个人都叫醒,但是也只能有一个人来开车。
这个故事可以用来比喻线程编程模型思想。这里的司机就是线程,汽车可以理解为共享数据,轻推和大声说话就是通信机制,个体在等待这些事件的发生。
多线程模型具有以下优点:
<1> 在多处理器系统中开发程序的并行性。除了并行性这一优点是需要特殊硬件支持外,其他优点对硬件不做要求。
在多处理器系统中,线程模式可以让一个进程同时执行多个独立运算。一个运行在双CPU上的计算密集型多线程程序几乎可以获得传统的单线程程序两倍的性能。对于并行能带来多大的性能提升,可以Amdahl法则预测:
                ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​         ​​​​​​​                                             
在Amdahl法则登时中,p代表可并行代码与整个执行时间的比率,n代表代码可以使用的处理器的数目。并行工作真个延续时间就等于非并行时间(1-p)的延续时间加上每个处理器执行并行工作(p/n)的延续时间。
<2> 在等待慢速外设I/O操作结束的同时,程序可以执行其他计算,为程序的并发提供更有效,更自然的开发方式。
如果事件不是并发的,程序一次只能做一件事情,如大型数据库排序,用户界面可能相当长的时间内无法响应用户的操作;如果实践引发长时间等待,如通过低速网络连续读取数据,用户也只能再次等待。另一方面,你可以创建一个转么排序数据库的线程,或者从网上读取数据而让用户界面线程立即处理另一用户操作。慢速操作继续执行,而程序还可以相应。
<3> 一种模块化编程模型,能清晰地表达程序中独立事件的相互关系。
即使你的代码从不在多处理器系统上运行,了解线程模型仍然很有意义。线程模型将独立的或者松耦合的功能执行流(线程)显示的分离。如果活动设计为线程,那么每个函数必须包括显示的同步以确保依赖关系。因为同步机制就是可执行的代码,所以依赖性改变时也无法忽略他。同步结构的存在阅读代码的人了解代码中的时间依赖关系,使代码维护更加容易,尤其是对于包含大量独立代码的大型程序而言。
多线程模型的缺陷:
<1> 计算负荷
线程代码中的负荷代价包括由于线程间同步所导致的。在几乎任何线程代码中你都需要使用某种同步机制,使用太多的同步很容易损失性能。
<2> 编程规则
尽管线程编程模型的基本思想简单,但是编写实际的代码不是件容易的事。编写能够在多个线程中良好工作的代码需要认真思考和计划。你需要明白同步协议和程序中的不变量,你不得不避免死锁,竞争和优先级倒置。
<3> 更难调试
提供线程功能的系统通常将传统的串行调试工具扩展以提供基本的线程调试支持。系统会提供一个调试器,允许你看到所有线程的条用结构树,并设置只能在特定线程内激活的断点。系统可能提供某种形式的性能分析器,让你计算某个线程或者所有线程中函数的累计占有处理器时间。不幸的是,这仅仅是调试异步代码的开始,调试不可避免的改变事件的顺序。这在调试串行代码时不会有什么太大问题,但是调试异步代码时却是致命的。
何时使用多线程:
最适合使用线程的是实现以下功能的应用:
<1> 计算密集型应用,为了能在多处理器系统上运行,将这些计算分解到多个线程中实现;
<2> I/O密集型应用,为提高性能,将I/O操作重叠。很多线程可以同时等待不同的I/O操作。
多线程的创建和使用:
<1> 创建线程
#include <pthread.h>
pthread_create(thread, attr, start_routine, arg)
参数:
thread               指向线程标识符指针。
attr                    一个不透明的属性对象,可以用来设置线程属性。默认值是NULL。
start_routine     线程运行函数起始地址,一旦线程被创建就会运行。
arg                    运行函数的参数。
<2> 终止线程
#include <pthread.h>
pthread_exit(status)
#include < iostream > // 必须的头文件 
#include < pthread.h >
using namespace std ;
#define NUM_THREADS 5 // 线程的运行函数
void * say_hello ( void * args ) {
    cout << " Hello Runoob! " << endl ; return 0 ; 
} 
int main ( ) { // 定义线程的 id 变量,多个变量使用数组 
    pthread_t tids [ NUM_THREADS ] ;
    for ( int i = 0 ; i < NUM_THREADS ; ++ i ) { //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数 
    int ret = pthread_create ( & tids [ i ] , NULL , say_hello , NULL ) ; 
        if ( ret != 0 ) {  
            cout << " pthread_create error: error_code= " << ret << endl ; 
        } 
    }
    //等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过来;
    pthread_exit ( NULL ) ;
}
<3>连接和分离线程
pthread_join(threadid, status);
pthread_detach(threadid);
pthread_join()子程序阻碍调用程序,直到指定的threadid线程终止为止。当创建一个线程时,它的属性
会定义它是否可连接的或可分离的。只有创建时定义为可连接的线程才可以被连接。如果线程创建时被定
义为可分离的,则永远也不能被连接。
#include < iostream > 
#include < cstdlib >
#include < pthread.h > 
#include < unistd.h >
using namespace std ;
#define NUM_THREADS 5 
void * wait ( void * t ) {  
    int i ; 
    long tid ; 
    tid =
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
pthread是一种使用C语言编写的多线程库,它可以方便地实现多线程并行编程。使用pthread库,我们可以在一个进程中创建多个线程,每个线程可以同时执行不同的任务,以实现并行处理。 pthread库的优势主要有以下几点: 1. 提高程序的运行效率:多线程可以将一个任务划分成若干个子任务,每个子任务由一个线程处理,从而充分利用多核处理器的性能,提高程序的运行效率。 2. 提升程序的响应性能:多线程可以将繁重的计算或耗时的任务放在后台线程中进行处理,使得前台线程能够响应用户的操作,提升程序的响应性能。 3. 简化编程复杂度:使用pthread库可以方便地创建、管理和控制多个线程,提供了丰富的线程相关的函数和工具,可以简化多线程编程的复杂度。 在pthread多线程并行编程中,我们需要注意以下几点: 1. 线程的创建和销毁:使用pthread库可以通过pthread_create函数创建一个新线程,并通过pthread_join函数等待线程的结束。在合适的时机,我们需要使用pthread_exit函数主动退出线程,以释放资源。 2. 线程的同步和互斥:多个线程之间可能会访问共享资源,我们需要使用pthread_mutex_t互斥锁来确保同一时间只有一个线程可以访问共享资源,以避免竞争条件的发生。 3. 线程的通信和协作:线程之间可以通过共享内存、全局变量等方式进行通信。多个线程之间可以通过条件变量(pthread_cond_t)和信号量(sem_t)等机制进行协作,实现任务的分配和控制。 总之,pthread多线程并行编程可以充分利用多核处理器的性能,实现任务的并行处理,提高程序的运行效率和响应性能。但在编程过程中需要注意线程的创建和销毁、线程的同步和互斥、线程的通信和协作等问题,以确保多线程程序的正确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值