`

并行计算学习之Pthread

阅读更多

1.线程与进程

 

   相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。在串行程序基础上引入线程和进程是为了提高程序的并发度,从而提高程序运行效率和响应时间。

 

    线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

 

 

2.Pthread基本概念

       Pthread是一套通用的线程库, 它广泛的被各种Unix所支持, 是由POSIX提出的. 因此, 它具有很好的客移植性. 在Linux上, 由于它是通过内核级线程来实现的, 就没有完全的实现它. 但从功能上来看, 它丝毫不逊色.

 

3.Pthread函数

   (1).创建线程

      int pthread_create (pthread_t *THREAD,pthread_attr_t * ATTR,void * (*START_ROUTINE)(void *),void * ARG);
   第一个参数是一个pthread_t型的指针用于保存线程id. 以后对该线程的操作都要用id来标示.
   第二个参数是一个pthread_attr_t的指针用于说明要创建的线程的属性, 使用NULL, 表示要使用缺省的属性.
   第三个参数指明了线程的如口, 是一个只有一个(void *)参数的函数.
   第四个参数指明了要传到线程如口函数的参数.

  pthread_create 返回值
  pthread_create() 在调用成功完成之后返回零。其他任何返回值都表示出现了错误。如果检测到以下任一情况,pthread_create() 将失败并返回相应的值。

  (2).等待线程终止

   pthread_join() 函数会一直阻塞调用线程,直到指定的线程终止。

  (3)分离线程
    pthread_detach(3C) 是 pthread_join(3C) 的替代函数,可回收创建时 detachstate 属性设置为 PTHREAD_CREATE_JOINABLE 的线程的存储空间。

  (4)终止线程
   使用 pthread_exit(3C) 终止线程。

 

    在POSIX线程API中提供了一个pthread_cleanup_push()/pthread_cleanup_pop()函数对用于自动释放资源--pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用pthread_exit()和取消点终止)都将执行pthread_cleanup_push()所指定的清理函数。API定义如下:

void pthread_cleanup_push(void (*routine) (void *), void *arg)

void pthread_cleanup_pop(int execute)

 

4.线程同步

   (1).创建和销毁

   有两种方法创建互斥锁,静态方式和动态方式。

  POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,

  方法如下: pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

     Linux Threads实现中,pthread_mutex_t是一个结构,而PTHREAD_MUTEX_INITIALIZER则是一个结构常量。

 

   动态方式是采用pthread_mutex_init()函数来初始化互斥锁,API定义如下:

    int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)

    其中mutexattr用于指定互斥锁属性(见下),如果为NULL则使用缺省属性。

 

    pthread_mutex_destroy()用于注销一个互斥锁,API定义如下:

    int pthread_mutex_destroy(pthread_mutex_t *mutex)

   销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。

  由于在Linux中,互斥锁并不占用任何资源,因此Linux Threads中的pthread_mutex_destroy()除了检查锁状态以外(锁定状态则返回EBUSY)没有其他动作。

  (2).锁操作

 

     锁操作主要包括加锁pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁pthread_mutex_trylock()三个。
    不论哪种类型的锁,都不可能被两个不同的线程同时得到,而必须等待解锁。对于普通锁和适应锁类型,解锁者可以是同进程内任何线程;而检错锁则必须由加锁者解锁才有效,否则返回EPERM;对于嵌套锁,文档和实现要求必须由加锁者解锁,但实验结果表明并没有这种限制,这个不同目前还没有得到解释。在同一进程中的线程,如果加锁后没有解锁,则任何其他线程都无法再获得锁。

int pthread_mutex_lock(pthread_mutex_t *mutex)

int pthread_mutex_unlock(pthread_mutex_t *mutex)

int pthread_mutex_trylock(pthread_mutex_t *mutex)

 

pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待。

  (3).条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

 

5.一个例子

 

#include <pthread.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>

#define MaxThreadNum 32  
#define kSamplePoints 100000000  
#define kSpace 1  

void *compute_pi(void *);
inline double WallTime();

int total_hits, hits[MaxThreadNum][kSpace];
int sample_points_per_thread, num_threads;
pthread_mutex_t MUTEX;
int main(void)
{
    int i;  
    double time_start, time_end;

    pthread_t p_threads[MaxThreadNum];

    pthread_mutex_init(&MUTEX,NULL);
    printf("Enter num_threads\n");
    scanf("%d", &num_threads);
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
    time_start = WallTime();

    total_hits = 0;  
    sample_points_per_thread = kSamplePoints / num_threads;

    for(i=0; i<num_threads; i++)
    {
        pthread_create(&p_threads[i], &attr, compute_pi, (void *)i);
    }

    for(i=0; i<num_threads; i++)
    {
        pthread_join(p_threads[i], NULL);
        total_hits += hits[i][0];
    }

    double pi = 4.0 * (double)total_hits / kSamplePoints;
    time_end = WallTime();  
    printf("Elasped time: %lf, Pi: %lf\n", time_end - time_start, pi);
    return 0;
 
}
void *compute_pi(void * s)
{
    unsigned int seed;
    int i;

    double rand_no_x, rand_no_y;

    seed =(int) s;
    /*local_hits = 0;*/

    for(i=0; i<sample_points_per_thread; i++)
    {
        rand_no_x = (double)(rand_r(&seed))/(double)(RAND_MAX);
        rand_no_y = (double)(rand_r(&seed))/(double)(RAND_MAX);
        if((rand_no_x - 0.5)*(rand_no_x - 0.5) + (rand_no_y - 0.5) * (rand_no_y - 0.5) < 0.25)
        {
         pthread_mutex_lock(&MUTEX);
           total_hits++;
         pthread_mutex_unlock(&MUTEX);
        }
        seed *= i;
    }
    pthread_exit(0);
}

inline double WallTime()
{
    struct timeval tv;
    struct timezone tz;

    gettimeofday(&tv, &tz);

    double currTime = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0;

    return currTime;
}

 

 

分享到:
评论

相关推荐

    天津大学并行计算Pthread实验代码(C++)

    在“天津大学并行计算Pthread实验”中,学生将通过C++编程语言学习如何利用Pthread库来实现并行计算。 首先,我们来看"实验代码cpp版"。这个文件包含了一个C++程序,该程序设计用于并行计算特定的数学问题,可能是...

    并行pthread求π算法

    并行pthread求π算法是一种利用多线程技术来提高计算效率的...总之,pthread求π的实现涉及了多线程编程、并行计算、数值方法等多个方面的知识,是一个综合性的学习项目,对于提升编程技能和理解并行计算有重要的意义。

    并行计算相关书籍

    并行计算是现代计算机科学中的一个重要领域,它涉及在多个处理器或计算机之间同时处理任务,以提高计算效率和解决问题的速度。以下是对标题和描述中提到的三本书的主要知识点的详细阐述: 1. 《并行计算——结构....

    高斯消元法pthread并行算法

    在本例中,`pthread`库被用来实现多线程并行计算。`pthread`(POSIX线程)是跨平台的线程API,广泛应用于Unix-like系统,包括Linux和macOS,它允许开发者创建和管理多个并发执行的线程。 在VS2015环境下,`pthread`...

    mpi.rar_MPI_mapReduce_pthread mpi_并行计算

    本实验以"mpi.rar"压缩包为载体,主要涵盖了MPI(Message Passing Interface)、MapReduce以及pthread库在并行计算中的应用,特别是用于寻找历史最高气温的算法。 首先,MPI,全称Message Passing Interface,是一...

    基于共享内存的并行计算

    在基于共享内存的并行计算环境中,Pthread提供了丰富的API来支持线程的创建、同步和通信等功能,是实现并行程序的重要工具之一。 在并行计算中,合理设计线程的数量和分配策略对于提升系统的整体性能至关重要。例如...

    pthread多线程求pi,linux多线程pthread,C,C++

    在IT领域,多线程是一种常见且强大的编程技术,它允许多个任务同时执行...这三份源代码文件为我们提供了学习和实践多线程并行计算的宝贵资源。通过分析和比较不同实现,我们可以更深入地了解并行计算的技巧和最佳实践。

    并行计算 + Posix

    通过本教材的学习,读者不仅能够掌握并行计算的基本原理和实践技巧,还能够熟悉Posix编程环境,从而具备开发跨平台、高效能应用的能力。在实际工作中,这将有助于解决性能瓶颈问题,优化系统资源利用率,提升软件的...

    并行计算程序设计

    ### 并行计算程序设计知识点解析 #### 一、并行计算与多核程序设计概览 **并行计算**是指同时使用多个处理器执行任务,从而显著提高计算效率的一种技术。随着多核处理器的普及,**多核程序设计**成为了并行计算的...

    并行计算基础知识讲座PPT教案学习.pptx

    在并行计算模型和语言方面,共享存储模型(如X3H5, Pthread, OpenMP)适用于PVP、SMP和DSM系统,而消息传递模型(如MPI,PVM)则适应于MPP、Cluster和COW系统。数据并行模型则着重于数据的并行处理,常见于并行计算...

    并行计算机架构与编程上机实验程序MPI.zip

    在并行计算中,大型矩阵的行列式计算可以被分解为多个子任务,分布到多个处理器上进行,从而显著提高计算速度。MPI提供了通信和同步的接口,使得分布在不同处理器上的进程能够协同工作。在这个实验中,"mpi2.cpp...

    并行矩阵乘法

    总的来说,这个项目提供了对并行计算和多线程编程的实际应用,对于理解并行矩阵乘法的原理和优化技巧非常有帮助。通过学习和实践,不仅可以提升C++编程能力,还能掌握如何利用多核处理器提高计算密集型任务的性能。

    pthread测试工程

    pthread是POSIX线程库,它是跨平台的多线程编程接口,被广泛应用于Linux、Unix和其他类Unix系统。在Windows环境下,通过第三方工具如MinGW或...这是一个很好的学习和实践平台,有助于提升你在多线程编程领域的技能。

    多线程矩阵乘法(java、win32、pthread三合一)

    矩阵乘法是计算密集型操作,如果能利用多线程并行计算,可以显著提高效率。下面将分别介绍在Java、Win32 API和pthreads库中实现多线程矩阵乘法的基本原理和方法。 首先,我们来看Java中的多线程实现。Java提供了...

    并行程序设计的入门之作

    总之,“并行程序设计的入门之作”提供了全面的学习材料,帮助你从零开始掌握并行计算的基础,通过Pthread、OpenMP和MPI的实践,你可以逐步提升自己的并行编程能力,为处理大规模计算问题打下坚实基础。

    pthread_pthread_

    - **科学计算**:在大规模并行计算中,PThread用于组织并行计算任务。 通过理解和熟练运用PThread,开发者可以构建出高效、可靠的多线程应用程序,充分发挥多核处理器的优势,提升软件的运行效率和用户体验。学习...

    求曼德勃罗集合C语言串行并行代码.zip

    学习这些代码可以帮助理解并行计算的基本原理,以及如何在实践中应用OpenMP和MPI。同时,它也可以作为研究分形几何和C语言编程的实例。对于计算机科学和工程的学生以及对并行计算感兴趣的开发者来说,这是一个有价值...

    求素数MPI Pthread的程序

    标题中的“求素数MPI Pthread的程序”指的是使用两种并行计算模型——Message Passing Interface (MPI) 和 POSIX Threads (Pthread) 编写的程序,用于寻找素数。这两个技术在分布式计算和多线程编程中是常见的工具,...

    东南大学 操作系统实验2 用pthread实现矩阵相乘

    本实验的主题是“用pthread实现矩阵相乘”,这是并行计算领域的一个经典问题,旨在利用多线程技术提高计算效率。pthread是POSIX线程库,广泛应用于Linux和其他符合POSIX标准的操作系统中。 矩阵相乘是计算密集型...

Global site tag (gtag.js) - Google Analytics