并行计算导论

顺序算法与并行算法

  1. 顺序算法:begin-end代码块,所有步骤都是通过单个任务依次执行的,每次执行一个步骤。当所有步骤执行完成时,算法完成。
  2. 并行算法:cobegin-coend代码块,所有任务都是并行执行的。下一个步骤将只在所有这些任务完成之后执行。

并行性与并发性

  1. 并行性:只能在有多个处理组件的系统中实现。
  2. 并发性:不同的任务只能并发执行,即在逻辑上并行执行。

线程

优点

  1. 线程创建和切换速度更快
  2. 线程的响应速度更快
  3. 线程更适合并行计算

缺点

  1. 需要来自用户的明确同步
  2. 许多库函数可能对线程不安全
  3. 在单CPU系统上,使用线程解决问题实际上要比使用顺序程序慢

线程操作

线程可在内核模式或用户模式下执行

线程管理函数

创建线程

pthread_create()函数:成功返回0,如果失败则返回错误代码

线程ID

pthread_equal()函数:比较线程ID,不同返回0

线程终止

线程函数结束后终止,或使用函数pthread_exit进行显示终止

0表示正常终止

线程连接

pthread_join:终止线程的退出状态一status_ptr返回

线程同步

当多个线程试图修改同一共享变量或数据结构时,如果修改结果取决于线程的执行顺序,则称之为竞态条件

互斥量

初始化

  1. 静态方法,如

    pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

    定义互斥量m

  2. 动态方法:pthread_mutex_init()函数

死锁预防

互斥量使用封锁协议

条件变量

作为锁,互斥量仅用于确保县城只能互斥地访问临界区中的共享数据对象

条件变量提供了一种线程协作的方法,初始化:

  1. 静态方法,如:

    pthread_cond_t con = PTHREAD_COND_INITIALIZER;

    定义一个条件变量con

  2. 动态方法:pthread_cond_init()函数

生产者—消费者问题

信号量

信号量是进程同步的一般机制。信号量是一种数据结构

屏障

在某些情况下,保持线程活动会更好,但应要求他们在所有线程都达到指定同步点之前不能继续活动。

Pthreads中,可以采用的机制是屏障以及一系列屏障函数。首先,主线程创建一个屏障对象:

pthread_barrier_t barrier;

并且调用

pthread_barrier_init(&barrier NULL, nthreads);初始化

工作线程使用

pthread_barrier_wait(&barrier)在屏障中等待指定数量的线程到达屏障

linux中的线程

linux不区分进程和线程

线程只是一个与其他进程共享某些资源的进程

进程和线程都是由clone()系统调用创建的,具有以下原型:

int clone(int (*fn)(coid *), void *child_stack, int flags, void *arg)

clone()更像是一个线程创建函数,flag字段详细说明父进程和子进程共享的资源,包括:

  • CLONE_VM:父进程和子进程共享地址空间
  • CLONE_FS:父进程和子进程共享文件系统信息
  • CLONE_FILES:父进程和子进程共享打开的文件
  • CLONE_SIGHAND:父进程和子进程共享信号处理函数和已屏蔽信号

问题和解决思路

pthread_cancel()不能杀死线程

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <pthread.h>
  5 #include <string.h>
  6 
  7 void *func(void *arg){
  8     while(1);
  9     return NULL;
 10 }
 11 int main(){
 12     printf("main:pid=%d,tid=%lu\n",getpid(),pthread_self());
 13 
 14     pthread_t tid;
 15     int ret = pthread_create(&tid,NULL,func,NULL);
 16     if(ret != 0){
 17         fprintf(stderr,"pthread_create error:%s\n",strerror(ret));
 18         return 1;
 19     }
 20 
 21     ret = pthread_cancel(tid);
 22     if(ret != 0){
 23         fprintf(stderr,"pthread_cancel error:%s\n",strerror(ret));
 24         return 2;
 25     }
 26 
 27     pthread_exit((void*)0);
 28 
 29     return 0;
 30 }

img

原因:

使用pthread_cancel()终止线程,需要线程中存在取消点。

大致是需要线程中有陷入内核的操作,才会存在取消点

如果想要用pthread_cancel()终止一个没有陷入内核操作的线程,就需要手动添加取消点

在while循环中加入,pthread_testcancel()即可用pthread_cancel()杀死该线程

  7 void *func(void *arg){
  8     while(1) pthread_testcancel();
  9     return NULL;
 10 }

img

原文地址:http://www.cnblogs.com/kenneth2012/p/16796409.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性