CN102902512A - 一种基于多线程编程及消息队列的多线程并行处理方法 - Google Patents
一种基于多线程编程及消息队列的多线程并行处理方法 Download PDFInfo
- Publication number
- CN102902512A CN102902512A CN2012103162117A CN201210316211A CN102902512A CN 102902512 A CN102902512 A CN 102902512A CN 2012103162117 A CN2012103162117 A CN 2012103162117A CN 201210316211 A CN201210316211 A CN 201210316211A CN 102902512 A CN102902512 A CN 102902512A
- Authority
- CN
- China
- Prior art keywords
- buf
- thread
- job
- queue
- task
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Images
Landscapes
- Image Processing (AREA)
- Debugging And Monitoring (AREA)
Abstract
本发明提供一种基于多线程编程及消息队列的多线程并行处理方法,属于计算机高性能计算领域。本发明对传统单线程串行软件的并行化进行改造,利用当前流行的多核CPU计算设备、pthread多线程并行计算技术及消息队列实现线程间通信的技术,其方法内容包括:在单节点内,创建三类pthread线程,分别为读、计算、写线程,并且各类线程数目灵活可配置,开辟多缓存,创建四个队列,用于线程间通信,调配计算任务及管理缓存空间资源。该方法广泛适用于具有多线程并行处理需求的应用场合,可指导软件开发人员对现有软件进行多线程化改造,实现软件对***资源利用最优化,显著提高硬件资源利用率,提高软件的计算效率和软件整体性能。
Description
技术领域
本发明涉及计算机应用技术领域, 具体地说是一种基于多线程编程及消息队列的多线程并行处理方法。
背景技术
硬件***在新技术的推动下进行着快速演进,表现出更好的性能、更低的价格,如传统CPU从单核向多核直至众核发展。但随着计算设备体系结构的多样化,多核化,软件***仅仅依靠硬件的更新从而获得性能提升的方式已经不符合现有硬件的发展趋势,例如传统的单线程串行程序在多核计算设备下不能表现出更好的性能。硬件发展的最终目的是推动应用软件的表现,进而推进整个计算***的性能。因此软件***不能仅仅依靠硬件性能的发展,而应该同时针对硬件***的发展进行软件***的再次开发和更新。这也是目前计算架构下我们遇到的最大挑战,而软件***的再次开发和改造则显得极为必要。目前国内外针对CPU多核体系结构的应用开发在CPU多核发展之初就如火如荼地展开了,并陆续开发或改造出相当数量的应用。随着多核体系结构处理器的普及,应用软件多线程并行处理方式将逐渐成为主流。
发明内容
本发明的目的是提供一种基于多线程编程及消息队列的多线程并行处理方法。
本发明的目的是按以下方式实现的,在单节点内,创建三类pthread线程,分别为读、计算、写线程,并且各类线程数目灵活可配置,开辟多缓存,创建四个队列,用于线程间通信,调配计算任务及管理缓存空间资源,具体步骤如下:
1.基于多缓冲和消息队列建立任务分发机制,包括:
1)计算任务的划分:任务划分的基本单位总的计算任务数是TOTAL_JOB,它可以被划分成多个子任务,定义每个子任务大小为JOB_SIZE,定义灵活的任务划分策略,软件有自动配置模式和用户手动配置模式;
2)任务分发、执行策略,包括:
(1)子任务实际由读线程来生成;读线程定义每个子任务的信息tmp_msg,包括:job_begin,job_size,buf_id;
其中:job_begin是该任务计数编号,通过它可以确定该任务的起始LINE号和CMP号;
job_size定义了该任务的大小,其上限是预先已经定义好的JOB_SIZE;
buf_id指明了该任务所在的BUF编号;
(2)任务信息tmp_msg的类型实际上就是消息队列成员的类型,被加入到各个队列中;
3)子任务执行所需资源的竞争策略完成一个子任务,需要如下几个步骤:
a) 读线程根据当前读取进度CURRENT_READ_STEP及总作业大TOTAL_STEP,确定当前任务的起始job_begin,任务大小job_size,并且从空SR_BUF队列SR_BUF_EMPTY_QUEUE中获取一个空的SR_BUF_ID,将数据读入SR_BUF_ID对应的SR_BUF中,即SR_BUF[SR_BUF_ID],然后将新生成的任务信息保存至tmp_msg中,并将tmp_msg加入新计算任务队列SR_BUF_FULL_QUEUE中;
b) 计算线程需先从新计算任务队列SR_BUF_FULL_QUEUE中获取一个新计算任务,然后再从空闲目标缓冲队列DR_BUF_EMPTY_QUEUE中获取一个空闲DR_BUF_ID,之后才进行计算,计算源数据为SR_BUF[SR_ BUF_ID],计算结果存放于DR_BUF[DR_BUF_ID]中,计算结束后,释放SR_BUF_ID对应的源数据缓存,即将SR_BUF_ID加入SR_BUF_EMPTY_QUEUE队列中,并告知写线程进行输出,即将tmp_msg加入到待输出队列DR_BUF_FULL_QUEUE中;
c) 写线程从待输出任务队列DR_BUF_FULL_QUEUE中获取一个写任务信息tmp_msg,该任务信息定义了数据存放的DR_BUF_ID以及该写任务需要写到的位置信息,即job_begin,以及写任务的规模job_size,写线程完成该输出任务后,需要告知计算线程DR_BUF[DR_BUF_ID]中的数据已经输出完毕,可重新用于存放计算结果, 即将DR_BUF_ID加入DR_BUF_EMPTY_QUEUE队列中;
2.多缓冲设计
设计多个源数据缓冲SR_BUF和目标数据缓冲DR_BUF,缓冲的数目灵活可调,为了以最少的缓冲达到最高的效能,缓冲的个数有一个临限值,理论上,源缓冲与目标缓冲的数目至少为计算线程数的2倍,即:
SR_BUF_NUM>=2*COMPUTE_THREAD_NUM,DR_BUF_NUM>= 2*COMPUTE_THREAD_NUM
考虑到实际生产中网络资源的竟争和不稳定因素,保证计算线程随时都能获得一个源缓冲和一个目标缓冲,软件为每个计算线程预留一个缓冲余量,默认将源数据缓冲和目标缓冲数都设置为计算线程数的3倍;
3.环形消息队列设计
为了实现上述任务分发策略,设计以下四个队列:
消息队列 | 生产者 | 消费者 | 初始状态 | 备注 |
SR_BUF_EMPTY_QUEUE | COMPUTE_thread | READ_thread | SR_BUF_ID全部入队 | 空SR_BUF队列 |
SR_BUF_FULL_QUEUE | READ_thread | COMPUTE_thread | 空 | 满SR_BUF队列 |
DR_BUF_EMPTY_QUEUE | WRITE_thread | COMPUTE_thread | DR_BUF_ID全部入队 | 空DR_BUF队列 |
DR_BUF_FULL_QUEUE | COMPUTE_thread | WRITE_thread | 空 | 满DR_BUF队列 |
其中消息队列中存放的消息数据类型定义如下:
1) SR_BUF_FULL_QUEUE:新的计算任务队列新计算任务消息队列,记录作业信息JOB_INFO(包括JOB_BEGIN,JOB_SIZE,SR_BUF_ID),由读线程写入(生产),计算线程弹出(消费)当读线程向SR_BUF_ID读入新数据时,将JOB_INFO入队,计算线程弹出JOB_INFO时,计算SR_BUF_ID对应的源数据;
2) SR_BUF_EMPTY_QUEUE: 存放当前空闲SR_BUF_ID号源缓冲释放消息队列,与SR_BUF_FULL_QUEUE功能相反,由计算线程写入,读线程弹出,当SR_BUF_ID对应的任务计算完毕时,释放SR_BUF_ID,告知读线程可对其更新数据;
3) DR_BUF_EMPTY_QUEUE: 存放当前空闲DR_BUF_ID号目标缓冲为空消息队列,记录DR_BUF_ID号,由写线程写入,计算线程弹出;
当写线程对DR_BUF_ID数据输出完毕时,将DR_BUF_ID入队,告知计算线程,该DR_BUF_ID输出完毕可重新用于计算,计算线程弹出DR_BUF_ID时,启动计算,并将结果写入DR_BUF_ID对应的目标缓冲中;
4) DR_BUF_FULL_QUEUE: 新的写任务队列新写任务消息队列,记录作业信息JOB_INFO,包括JOB_BEGIN,JOB_SIZE,DR_BUF_ID,由计算线程写入,写线程弹出;
当计算线程向DR_BUF_ID读入新数据时,将JOB_INFO入队,写线程弹出JOB_INFO时,对DR_BUF_ID对应的目标数据进行输出;
4.线程设计
1)主线程设计
(1)主线程功能及运行流程如下:
参数预处理;
定义读、计算、写线程数;
定义源、目标缓存数目,与计算线程数相关;
定义任务划分粒度,即子任务规模JOB_SIZE;
开辟源、目标缓冲内存空间;
创建并初始化消息队列、锁、信号量;
创建并启动读、计算、写线程;
等待所有线程退出;
其它处理;
程序退出;
(2)线程伪代码
1. INIT(PARA);
2. SET(THREAD_NUM);
3. SET(BUF_NUM);
4. SET(JOB_SIZE)
5. CREATE(OUTPUT_FILE_LIST);
6. MALLOC(BUF);
7. INIT(QUEUE);
8. INIT(MUTEX);
9. INIT(SEM);
10. INIT(PROGRESS,Total_Step);
11. CREATE(THREADS);
12. WHILE State_Flag && !wasCancelled && progress<=Total_Step
13. IF PROGRESSS.wasCancelled()
14. wasCancelled=true;
15. break;
16. ENDIF
17. IF ! State_Flag
18. breadk
19. ENDIF
20. SEM_WAIT(progress_sm);
21. progress+=JOB_SIZE;
22. SET_PROGRESS(progress);
23. DONE
24. JOIN(THREADS);
25. IF State_Flag && !wasCancelled
26. CREATESEIS_INDEX(OUTPUT_FILE_LIST);
27. ELSE
28. DELETESEIS_OBJ(OUTPUT_FILE_LIST);
29. ERROR_PROCESS();
30. EXIT
31. ENDIF
32. DELETE(PROGRESS);
33. DELETE( BUF);
34. DESTROY(MUTEX);
35. DESTROY(SEM);
36. PRINTF(LOG);
37. EXIT;
2) 读线程设计
(1)线程数设计
根据实际应用需求,灵活设置读线程数,默认只设置一个读线程;
(2)线程功能及运行流程
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步骤9,否则进入步聚3;
3.检查当前任务进度READ_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤9,否则进入步聚4;
4.根据当前读进度READ_CURRENT_STEP和总任务数Total_Step,计算剩余任务数left_job,生成新任务起始job_begin及大小信息Job_size,job_size上限为JOB_SIZE,更新任务计数READ_CURRENT_STEP;
5.从SR_BUF_EMPTY_QUEUE队列中获得一个空闲SR_BUF_ID;
6.从源文件INPUT_FILE中读取任务源数据至源数据缓存SR_BUF[SR_BUF_ID]中;
7.将该任务信息tmp_msg加入新计算任务队列SR_BUF_FULL_QUEUE中;
8.返回步骤2;
9.线程退出;
(3)线程伪代码
1. INIT
2. WHILE State_Flag && !wasCancelled
3. IF READ_CURRENT_STEP <= Total_Step
4. job_begin=READ_CURRENT_STEP;
5. job_left=Total_Step-READ_CURRENT_STEP;
6. IF job_left>JOB_SIZE
7. job_size=JOB_SIZE;
8. ELSE
9. job_size=job_left;
10. READ_CURRENT_STEP += job_size;
11. tmp_msg = SR_BUF_EMPTY_QUEUE.pop();
12. SR_BUF_id=tmp_msg.buf_id;
13. READ(INPUT_FILE,SR_BUF[SR_BUF_id])
14. tmp_msg(job_begin,job_size,SR_BUF_id);
15. SR_BUF_FULL_QUEUE.push(tmp_msg);
16. ELSE
17. pthread_exit();
18. ENDIF
19. DONE
20. pthread_exit();
3) 计算线程设计
(1)线程数设计:
默认情况下,计算线程数为***可用CPU核数,即SYS_CPU_CORE_NUM,用户通过宏COMPUTE_THREAD_NUM来定义计算线程数;
(2)线程功能及运行流程:
1)参数初始化;
2)检查错误标志及用户行为,如果出错或被用户取消,则进入步聚10,否则进入步聚3;
3)检查当前任务进度COMPUTE_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤10,否则进入步聚4;
4)从新计算任务队列SR_BUF_FULL_QUEUE中获取一个任务信息tmp_msg,其包含了任务的起始信息job_begin,大小信息job_size,以及任务数据存放源缓冲编号SR_BUF_ID,并更新任务计数COMPUTE_CURRENT_STEP;
5)从DR_BUF_EMPTY_QUEUE队列中获得一个空闲的DR_BUF_ID;
6)以SR_BUF[SR_BUF_ID]为数据输入缓存,以DR_BUF[DR_BUF_ID]为数据输出缓存进行计算;
7)将SR_BUF_ID加入SR_BUF_EMPTY_QUEUE中,表示SR_BUF[SR_BUF_ID]所存的数据计算完毕,需要重新加载源数据;
8)根据计算任务信息,生成写任务信息,并将其加入到DR_BUF_FULL_QUEUE队列中,表示需要写线程进行输出;
9)返回步骤2;
10)线程退出;
(3)线程伪代码
1)INIT
2)WHILE State_Flag && !wasCancelled
3)IF COMPUTE_CURRENT_STEP <= Total_Step
4)tmp_msg=SR_BUF_FULL_QUEUE.pop()
5)job_begin=tmp_msg.job_begin;
6)job_size=tmp_msg.job_size;
7)SR_BUF_id =tmp_msg.buf_id;
8)COMPUTE_CURRENT_STEP+=job_size;
9)tmp_msg= DR_BUF_EMPTY_QUEUE.pop();
10) DR_BUF_id =tmp_msg.buf_id;
11)COMPUTE(INPUT_FILE,SR_BUF[SR_BUF_id],DR_BUF[DR_BUF_id])
12)tmp_msg(-1,-1,SR_BUF_id);
13) SR_BUF_EMPTY_QUEUE.push(tmp_msg);
14) tmp_msg(job_begin,job_size,DR_BUF_id);
15) DR_BUF_FULL_QUEUE.push(tmp_msg);
16) ELSE
17) pthread_exit();
18)ENDIF
19)DONE
20)pthread_exit();
4)写线程设计
(1)线程数设计
根据实际应用需求,灵活设置写线程数,默认只设置一个写线程;
(2)线程功能及运行流程
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步骤9,否则进入步聚3;
3.检查当前任务进度WRITE_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤9,否则进入步聚4;
4.从新写任务队列DR_BUF_FULL_QUEUE中获取一个写任务信息tmp_msg,其包含了任务的起始信息job_begin,大小信息job_size,以及任务数据存放目标缓冲编号DR_BUF_ID,并更新任务计数WRITE_CURRENT_STEP;
5.将目标缓存DR_BUF[DR_BUF_ID]中的数据输出至OUTPUT_FILE;
6.将DR_BUF_ID加入DR_BUF_EMPTY_QUEUE中,表示DR_BUF[DR_BUF_ID]所存的数据输出完毕,需要重新加载计算结果;
7.向主线程发送更新进度条信号;
8.返回步骤2;
9.线程退出;
(1)线程伪代码
1.INIT
2.WHILE State_Flag && !wasCancelled
3.IF WRITE_CURRENT_STEP <= Total_Step
4. tmp_msg = DR_BUF_FULL_QUEUE.pop();
5.job_begin=tmp_msg.job_begin;
6. job_size=tmp_msg.job_size;
7.DR_BUF_id=tmp_msg.buf_id;
8. WRITE_CURRENT_STEP+=job_size;
9.WRITE(OUTPUT_FILE,DR_BUF[DR_BUF_id])
10. tmp_msg(-1,-1,DR_BUF_id);
11. DR_BUF_EMPTY_QUEUE.push(tmp_msg);
12.SEM_POST (progress_sem);
13.ELSE
14.pthread_exit();
15.ENDIF
16.DONE
17.pthread_exit()。
本发明的有益效果是:该方法广泛适用于具有多线程并行处理需求的应用场合,指导软件开发人员以较短的开发周期,较低的开发成本,快速高效地对现有软件进行多线程化改造,实现软件对***资源利用最优化,读数据,计算,写回数据的互相掩盖,最大限度地缩短软件运行时间,显著提高硬件资源利用率,提高软件的计算效率和软件整体性能。
附图说明
图1是***运行时序图;
图2是数据并发处理时序图。
具体实施方式
结合附图1和附图2对本发明的一种基于pthread及消息队列的多线程并行处理方法作进一步详细说明。
本发明的一种基于pthread及消息队列的多线程并行处理方法,是对传统单线程串行软件的并行化进行改造,利用当前流行的多核CPU计算设备、pthread多线程并行计算技术及消息队列实现线程间通信的技术,最大化提升硬件计算资源利用率,提升软件运行效能的通用方法。
本发明所提方法的内容包括:在单节点内,创建三类pthread线程,分别为读、计算、写线程,并且各类线程数目灵活可配置,开辟多缓存,创建四个队列,用于线程间通信,调配计算任务及管理缓存空间资源。
为了使本发明的目的、技术方案和优点更加清晰,下面详细描述本发明所述方法的实现过程。
1. 基于多缓冲和消息队列建立任务分发机制
1) 计算任务的划分
(1) 任务划分的基本单位总的计算任务数是TOTAL_JOB,它可以被划分成多个子任务,我们定义,每个子任务大小为JOB_SIZE;
(2) 子任务规模的制约因素及权衡考量
a)存储容量的限制
由于我们需要大量的源缓冲和目标缓冲,所以存储容量限制是定义JOB_SIZE的重要考量因素;
b)总任务规模限制
子任务大小的上限就是总任务规模,即整个作业当成一个子任务来完成;
c)计算线程数考量
合理确定任务划分粒度,尽量保证每个计算线程都能分到计算任务,最大限度地实现读、计算、写时间的掩盖;
综合以上考量,我们定义灵活的任务划分策略,软件有自动配置模式和用户手动配置模式。
2)任务分发、执行策略
(1)子任务实际由读线程来生成;
读线程定义每个子任务的信息tmp_msg,主要包括job_begin,job_size,buf_id,其中:
job_begin是该任务计数编号,通过它可以确定该任务的起始LINE号和CMP号;
job_size定义了该任务的大小,其上限是预先已经定义好的JOB_SIZE;
buf_id指明了该任务所在的BUF编号;
(2)任务信息tmp_msg的类型实际上就是消息队列成员的类型,被加入到各个队列中;
(3)子任务执行所需资源的竞争策略
完成一个子任务,需要如下几个步骤:
a) 读线程根据当前读取进度CURRENT_READ_STEP及总作业大TOTAL_STEP,确定当前任务的起始job_begin,任务大小job_size,并且从空SR_BUF队列SR_BUF_EMPTY_QUEUE中获取一个空的SR_BUF_ID,将数据读入SR_BUF_ID对应的SR_BUF中,即SR_BUF[SR_BUF_ID],然后将新生成的任务信息保存至tmp_msg中,并将tmp_msg加入新计算任务队列SR_BUF_FULL_QUEUE中;
b) 计算线程需先从新计算任务队列SR_BUF_FULL_QUEUE中获取一个新计算任务,然后再从空闲目标缓冲队列DR_BUF_EMPTY_QUEUE中获取一个空闲DR_BUF_ID。之后才进行计算,计算源数据为SR_BUF[SR_ BUF_ID],计算结果存放于DR_BUF[DR_BUF_ID]中,计算结束后,释放SR_BUF_ID对应的源数据缓存,即将SR_BUF_ID加入SR_BUF_EMPTY_QUEUE队列中,并告知写线程进行输出,即将tmp_msg加入到待输出队列DR_BUF_FULL_QUEUE中;
c) 写线程从待输出任务队列DR_BUF_FULL_QUEUE中获取一个写任务
信息tmp_msg,该任务信息定义了数据存放的DR_BUF_ID以及该写任务需要写到的位置信息,即job_begin,以及写任务的规模job_size。写线程完成该输出任务后,需要告知计算线程DR_BUF[DR_BUF_ID]中的数据已经输出完毕,可重新用于存放计算结果, 即将DR_BUF_ID加入DR_BUF_EMPTY_QUEUE队列中。
多缓冲设计
设计多个源数据缓冲SR_BUF和目标数据缓冲DR_BUF,缓冲的数目灵活可调,为了以最少的缓冲达到最高的效能,缓冲的个数有一个临限值,理论上,源缓冲与目标缓冲的数目至少为计算线程数的2倍,即SR_BUF_NUM >=2*COMPUTE_THREAD_NUM,DR_BUF_NUM >= 2*COMPUTE_THREAD_NUM。考虑到实际生产中网络资源的竟争和不稳定因素,保证计算线程随时都能获得一个源缓冲和一个目标缓冲,软件为每个计算线程预留一个缓冲余量,默认将源数据缓冲和目标缓冲数都设置为计算线程数的3倍。
环形消息队列设计
为了实现上述任务分发策略,我们设计以下四个队列:
其中消息队列中存放的消息数据类型定义如下:
1)SR_BUF_FULL_QUEUE:新的计算任务队列:新计算任务消息队列,记录作业信息JOB_INFO(包括JOB_BEGIN,JOB_SIZE,SR_BUF_ID),由读线程写入(生产),计算线程弹出(消费)当读线程向SR_BUF_ID读入新数据时,将JOB_INFO入队,计算线程弹出JOB_INFO时,计算SR_BUF_ID对应的源数据;
2)SR_BUF_EMPTY_QUEUE: 存放当前空闲SR_BUF_ID号源缓冲释放消息队列,与SR_BUF_FULL_QUEUE功能相反,由计算线程写入(生产),读线程弹出(消费)当SR_BUF_ID对应的任务计算完毕时,释放SR_BUF_ID,告知读线程可对其更新数据;
3)DR_BUF_EMPTY_QUEUE: 存放当前空闲DR_BUF_ID号目标缓冲为空消息队列,记录DR_BUF_ID号,由写线程写入(生产),计算线程弹出(消费);
当写线程对DR_BUF_ID数据输出完毕时,将DR_BUF_ID入队,告知计算线程,该DR_BUF_ID输出完毕可重新用于计算,计算线程弹出DR_BUF_ID时,启动计算,并将结果写入DR_BUF_ID对应的目标缓冲中;
4)DR_BUF_FULL_QUEUE: 新的写任务队列新写任务消息队列,记录作业信息JOB_INFO(包括JOB_BEGIN,JOB_SIZE,DR_BUF_ID),由计算线程写入(生产),写线程弹出(消费)。
当计算线程向DR_BUF_ID读入新数据时,将JOB_INFO入队,写线程弹出JOB_INFO时,对DR_BUF_ID对应的目标数据进行输出。
线程设计
1)主线程设计
(1)主线程功能及运行流程
1. 参数预处理;
2. 定义读、计算、写线程数;
3. 定义源、目标缓存数目,与计算线程数相关;
4. 定义任务划分粒度,即子任务规模JOB_SIZE;
5. 开辟源、目标缓冲内存空间;
6. 创建并初始化消息队列、锁、信号量;
7. 创建并启动读、计算、写线程;
8. 等待所有线程退出;
9. 其它处理;
10. 程序退出;
(2)线程伪代码
1. INIT(PARA);
2. SET(THREAD_NUM);
3. SET(BUF_NUM);
4. SET(JOB_SIZE)
5. CREATE(OUTPUT_FILE_LIST);
6. MALLOC(BUF);
7. INIT(QUEUE);
8. INIT(MUTEX);
9. INIT(SEM);
10. INIT(PROGRESS,Total_Step);
11. CREATE(THREADS);
12. WHILE State_Flag && !wasCancelled && progress<=Total_Step
13. IF PROGRESSS.wasCancelled()
14. wasCancelled=true;
15. break;
16. ENDIF
17. IF ! State_Flag
18. breadk
19. ENDIF
20. SEM_WAIT(progress_sm);
21. progress+=JOB_SIZE;
22. SET_PROGRESS(progress);
23. DONE
24. JOIN(THREADS);
25.IF State_Flag && !wasCancelled
26. CREATESEIS_INDEX(OUTPUT_FILE_LIST);
27.ELSE
28. DELETESEIS_OBJ(OUTPUT_FILE_LIST);
29. ERROR_PROCESS();
30. EXIT
31.ENDIF
32.DELETE(PROGRESS);
33.DELETE( BUF);
34.DESTROY(MUTEX);
35.DESTROY(SEM);
36.PRINTF(LOG);
37.EXIT
2)读线程设计
(1)线程数设计
根据实际应用需求,灵活设置读线程数,默认只设置一个读线程。
(2)线程功能及运行流程
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步骤9,否则进入步聚3;
3.检查当前任务进度READ_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤9,否则进入步聚4;
4.根据当前读进度READ_CURRENT_STEP和总任务数Total_Step,计算剩余任务数left_job,生成新任务起始job_begin及大小信息Job_size,job_size上限为JOB_SIZE,更新任务计READ_CURRENT_STEP;
5.从SR_BUF_EMPTY_QUEUE队列中获得一个空闲SR_BUF_ID;
6.从源文件INPUT_FILE中读取任务源数据至源数据缓存SR_BUF[SR_BUF_ID]中;
7.将该任务信息tmp_msg加入新计算任务队列SR_BUF_FULL_QUEUE中;
8.返回步骤2;
9.线程退出。
)线程伪代码
1.INIT
2.WHILE State_Flag && !wasCancelled
3. IF READ_CURRENT_STEP <= Total_Step
4. job_begin=READ_CURRENT_STEP;
5. job_left=Total_Step-READ_CURRENT_STEP;
6. IF job_left>JOB_SIZE
7.job_size=JOB_SIZE;
8.ELSE
9. job_size=job_left;
10. READ_CURRENT_STEP += job_size;
11. tmp_msg = SR_BUF_EMPTY_QUEUE.pop();
12. SR_BUF_id=tmp_msg.buf_id;
13. READ(INPUT_FILE,SR_BUF[SR_BUF_id])
14.tmp_msg(job_begin,job_size,SR_BUF_id);
15. SR_BUF_FULL_QUEUE.push(tmp_msg);
16. ELSE
17.pthread_exit();
18. ENDIF
19.DONE
20.pthread_exit();
4)计算线程设计
(1)线程数设计
默认情况下,计算线程数为***可用CPU核数,即SYS_CPU_CORE_NUM。用户可以通过宏COMPUTE_THREAD_NUM来定义计算线程数。
(2)线程功能及运行流程
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步聚10,否则进入步聚3;
3.检查当前任务进度COMPUTE_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤10,否则进入步聚4;
4.从新计算任务队列SR_BUF_FULL_QUEUE中获取一个任务信息tmp_msg,其包含了任务的起始信息job_begin,大小信息job_size,以及任务数据存放源缓冲编号SR_BUF_ID,并更新任务计数 COMPUTE_CURRENT_STEP;
5.从DR_BUF_EMPTY_QUEUE队列中获得一个空闲的DR_BUF_ID;
6.以SR_BUF[SR_BUF_ID]为数据输入缓存,以DR_BUF[DR_BUF_ID]为数据输出缓存进行计算;
7.将SR_BUF_ID加入SR_BUF_EMPTY_QUEUE中,表示SR_BUF[SR_BUF_ID]所存的数据计算完毕,需要重新加载源数据;
8.根据计算任务信息,生成写任务信息,并将其加入到DR_BUF_FULL_QUEUE队列中,表示需要写线程进行输出;
9.返回步骤2;
10.线程退出。
(3)线程伪代码
1.INIT
2.WHILE State_Flag && !wasCancelled
3. IF COMPUTE_CURRENT_STEP <= Total_Step
4. tmp_msg=SR_BUF_FULL_QUEUE.pop()
5.job_begin=tmp_msg.job_begin;
6. job_size=tmp_msg.job_size;
7.SR_BUF_id =tmp_msg.buf_id;
8. COMPUTE_CURRENT_STEP+=job_size;
9. tmp_msg= DR_BUF_EMPTY_QUEUE.pop();
10. DR_BUF_id =tmp_msg.buf_id;
11.COMPUTE(INPUT_FILE,SR_BUF[SR_BUF_id],DR_BUF[DR_BUF_id])
12.tmp_msg(-1,-1,SR_BUF_id);
13.SR_BUF_EMPTY_QUEUE.push(tmp_msg);
14.tmp_msg(job_begin,job_size,DR_BUF_id);
15. DR_BUF_FULL_QUEUE.push(tmp_msg);
16. ELSE
17.pthread_exit();
18.ENDIF
19.DONE
20.pthread_exit();
5)写线程设计
(1)线程数设计
根据实际应用需求,灵活设置写线程数,默认只设置一个写线程。
(2)线程功能及运行流程
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步骤9,否则进入步聚3;
3.检查当前任务进度WRITE_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤9,否则进入步聚4;
4.从新写任务队列DR_BUF_FULL_QUEUE中获取一个写任务信息tmp_msg,其包含了任务的起始信息job_begin,大小信息job_size,以及任务数据存放目标缓冲编号DR_BUF_ID,并更新任务计数WRITE_CURRENT_STEP;
5.将目标缓存DR_BUF[DR_BUF_ID]中的数据输出至OUTPUT_FILE;
6.将DR_BUF_ID加入DR_BUF_EMPTY_QUEUE中,表示DR_BUF[DR_BUF_ID]所存的数据输出完毕,需要重新加载计算结果;
7.向主线程发送更新进度条信号;
8.返回步骤2;
9.线程退出。
(3)线程伪代码
1.INIT
2.WHILE State_Flag && !wasCancelled
3.IF WRITE_CURRENT_STEP <= Total_Step
4. tmp_msg = DR_BUF_FULL_QUEUE.pop();
5. job_begin=tmp_msg.job_begin;
6.job_size=tmp_msg.job_size;
7. DR_BUF_id=tmp_msg.buf_id;
8.WRITE_CURRENT_STEP+=job_size;
9. WRITE(OUTPUT_FILE,DR_BUF[DR_BUF_id])
10.tmp_msg(-1,-1,DR_BUF_id);
11. DR_BUF_EMPTY_QUEUE.push(tmp_msg);
12.SEM_POST (progress_sem);
13. ELSE
14. pthread_exit();
15. ENDIF
16.DONE
17.pthread_exit();
5.性能测试及分析
将该方法应用于某个典型的石油行业应用软件模块多线程并行程序开发项目,并利用真实数据进行性能测试。
本次性能测试将针对不同规模的作业,利用不同规模的任务进行多次测试,并搜集测试数据,以进行性能分析。
1) 测试环境及测试数据
测试环境包括硬件环境、软件环境;
(1)测试硬件环境
(2)软件环境
操作***名称:RedHat Linux企业版,版本:5.3
编译器名称:Intel编译器,版本:10.1
数据库名称:Oracle数据库,版本:10g
应用***名称:某地震资料解释软件模块
(3)测试数据及作业规模
测试数据为真实生产的3D实际数据。
作业规模:通过CMP line和CMP数来控制作业规模,下表为作业具体参数:
2)性能测试结果
在浪潮英信NF8520四路服务器上进行了不同规模作业的测试,测试结果如下:
3)性能测试结果分析
利用该方法对该软件模块进行多线程并行化改造后,显著地提升了该软件模块的运行效率,以较短的开发周期,获得了较高的性能加速比。
除说明书所述的技术特征外,均为本专业人员的已知技术。
Claims (1)
1.一种基于多线程编程及消息队列的多线程并行处理方法,其特征在于在单节点内,创建三类pthread线程,分别为读、计算、写线程,并且各类线程数目灵活可配置,开辟多缓存,创建四个队列,用于线程间通信,调配计算任务及管理缓存空间资源,具体步骤如下:
基于多缓冲和消息队列建立任务分发机制,包括:
1)计算任务的划分:任务划分的基本单位总的计算任务数是TOTAL_JOB,它可以被划分成多个子任务,定义每个子任务大小为JOB_SIZE,定义灵活的任务划分策略,软件有自动配置模式和用户手动配置模式;
2)任务分发、执行策略,包括:
(1)子任务实际由读线程来生成;读线程定义每个子任务的信息tmp_msg,包括:job_begin,job_size,buf_id;
其中:job_begin是该任务计数编号,通过它可以确定该任务的起始LINE号和CMP号;
job_size定义了该任务的大小,其上限是预先已经定义好的JOB_SIZE;
buf_id指明了该任务所在的BUF编号;
(2)任务信息tmp_msg的类型实际上就是消息队列成员的类型,被加入到各个队列中;
3)子任务执行所需资源的竞争策略完成一个子任务,需要如下几个步骤:
读线程根据当前读取进度CURRENT_READ_STEP及总作业大TOTAL_STEP,确定当前任务的起始job_begin,任务大小job_size,并且从空SR_BUF队列SR_BUF_EMPTY_QUEUE中获取一个空的SR_BUF_ID,将数据读入SR_BUF_ID对应的SR_BUF中,即SR_BUF[SR_BUF_ID],然后将新生成的任务信息保存至tmp_msg中,并将tmp_msg加入新计算任务队列SR_BUF_FULL_QUEUE中;
计算线程需先从新计算任务队列SR_BUF_FULL_QUEUE中获取一个新计算任务,然后再从空闲目标缓冲队列DR_BUF_EMPTY_QUEUE中获取一个空闲DR_BUF_ID,之后才进行计算,计算源数据为SR_BUF[SR_ BUF_ID],计算结果存放于DR_BUF[DR_BUF_ID]中,计算结束后,释放SR_BUF_ID对应的源数据缓存,即将SR_BUF_ID加入SR_BUF_EMPTY_QUEUE队列中,并告知写线程进行输出,即将tmp_msg加入到待输出队列DR_BUF_FULL_QUEUE中;
写线程从待输出任务队列DR_BUF_FULL_QUEUE中获取一个写任务信息tmp_msg,该任务信息定义了数据存放的DR_BUF_ID以及该写任务需要写到的位置信息,即job_begin,以及写任务的规模job_size,写线程完成该输出任务后,需要告知计算线程DR_BUF[DR_BUF_ID]中的数据已经输出完毕,可重新用于存放计算结果, 即将DR_BUF_ID加入DR_BUF_EMPTY_QUEUE队列中;
多缓冲设计
设计多个源数据缓冲SR_BUF和目标数据缓冲DR_BUF,缓冲的数目灵活可调,为了以最少的缓冲达到最高的效能,缓冲的个数有一个临限值,理论上,源缓冲与目标缓冲的数目至少为计算线程数的2倍,即:
SR_BUF_NUM>=2*COMPUTE_THREAD_NUM,DR_BUF_NUM>= 2*COMPUTE_THREAD_NUM
考虑到实际生产中网络资源的竟争和不稳定因素,保证计算线程随时都能获得一个源缓冲和一个目标缓冲,软件为每个计算线程预留一个缓冲余量,默认将源数据缓冲和目标缓冲数都设置为计算线程数的3倍;
环形消息队列设计
为了实现上述任务分发策略,设计以下四个队列:
其中消息队列中存放的消息数据类型定义如下:
SR_BUF_FULL_QUEUE:新的计算任务队列新计算任务消息队列,记录作业信息JOB_INFO(包括JOB_BEGIN,JOB_SIZE,SR_BUF_ID),由读线程写入(生产),计算线程弹出(消费)当读线程向SR_BUF_ID读入新数据时,将JOB_INFO入队,计算线程弹出JOB_INFO时,计算SR_BUF_ID对应的源数据;
SR_BUF_EMPTY_QUEUE: 存放当前空闲SR_BUF_ID号源缓冲释放消息队列,与SR_BUF_FULL_QUEUE功能相反,由计算线程写入,读线程弹出,当SR_BUF_ID对应的任务计算完毕时,释放SR_BUF_ID,告知读线程可对其更新数据;
DR_BUF_EMPTY_QUEUE: 存放当前空闲DR_BUF_ID号目标缓冲为空消息队列,记录DR_BUF_ID号,由写线程写入,计算线程弹出;
当写线程对DR_BUF_ID数据输出完毕时,将DR_BUF_ID入队,告知计算线程,该DR_BUF_ID输出完毕可重新用于计算,计算线程弹出DR_BUF_ID时,启动计算,并将结果写入DR_BUF_ID对应的目标缓冲中;
DR_BUF_FULL_QUEUE: 新的写任务队列新写任务消息队列,记录作业信息JOB_INFO,包括JOB_BEGIN,JOB_SIZE,DR_BUF_ID,由计算线程写入,写线程弹出;
当计算线程向DR_BUF_ID读入新数据时,将JOB_INFO入队,写线程弹出JOB_INFO时,对DR_BUF_ID对应的目标数据进行输出;
线程设计
1)主线程设计
(1)主线程功能及运行流程如下:
1.参数预处理;
2.定义读、计算、写线程数;
3.定义源、目标缓存数目,与计算线程数相关;
4.定义任务划分粒度,即子任务规模JOB_SIZE;
5.开辟源、目标缓冲内存空间;
6.创建并初始化消息队列、锁、信号量;
创建并启动读、计算、写线程;
8.等待所有线程退出;
9.其它处理;
10程序退出;
(2)线程伪代码
1.INIT(PARA);
2.SET(THREAD_NUM);
3.SET(BUF_NUM);
4.SET(JOB_SIZE)
5.CREATE(OUTPUT_FILE_LIST);
6.MALLOC(BUF);
7.INIT(QUEUE);
8.INIT(MUTEX);
9.INIT(SEM);
10.INIT(PROGRESS,Total_Step);
11.CREATE(THREADS);
12.WHILE State_Flag && !wasCancelled && progress<=Total_Step
13.IF PROGRESSS.wasCancelled()
14.wasCancelled=true;
15.break;
16.ENDIF
17.IF ! State_Flag
18.breadk
19.ENDIF
20.SEM_WAIT(progress_sm);
21.progress+=JOB_SIZE;
22.SET_PROGRESS(progress);
23.DONE
24.JOIN(THREADS);
25.IF State_Flag && !wasCancelled
26.CREATESEIS_INDEX(OUTPUT_FILE_LIST);
27.ELSE
28.DELETESEIS_OBJ(OUTPUT_FILE_LIST);
29.ERROR_PROCESS();
30.EXIT
31.ENDIF
32.DELETE(PROGRESS);
33.DELETE( BUF);
34.DESTROY(MUTEX);
35.DESTROY(SEM);
36.PRINTF(LOG);
37.EXIT;
2)读线程设计
(1)线程数设计
根据实际应用需求,灵活设置读线程数,默认只设置一个读线程;
(2)线程功能及运行流程
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步骤9,否则进入步聚3;
3.检查当前任务进度READ_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤9,否则进入步聚4;
4.根据当前读进度READ_CURRENT_STEP和总任务数Total_Step,计算剩余任务数left_job,生成新任务起始job_begin及大小信息Job_size,job_size上限为JOB_SIZE,更新任务计数READ_CURRENT_STEP;
5.从SR_BUF_EMPTY_QUEUE队列中获得一个空闲SR_BUF_ID;
6.从源文件INPUT_FILE中读取任务源数据至源数据缓存SR_BUF[SR_BUF_ID]中;
7.将该任务信息tmp_msg加入新计算任务队列SR_BUF_FULL_QUEUE中;
8.返回步骤2;
9.线程退出;
3)线程伪代码
1.INIT
2.WHILE State_Flag && !wasCancelled
3.IF READ_CURRENT_STEP <= Total_Step
4.job_begin=READ_CURRENT_STEP;
5.job_left=Total_Step-READ_CURRENT_STEP;
6.IF job_left>JOB_SIZE
7.job_size=JOB_SIZE;
8.ELSE
9.job_size=job_left;
10.READ_CURRENT_STEP += job_size;
11.tmp_msg = SR_BUF_EMPTY_QUEUE.pop();
12.SR_BUF_id=tmp_msg.buf_id;
13.READ(INPUT_FILE,SR_BUF[SR_BUF_id])
14.tmp_msg(job_begin,job_size,SR_BUF_id);
15.SR_BUF_FULL_QUEUE.push(tmp_msg);
16.ELSE
17.pthread_exit();
18.ENDIF
19.DONE
20.pthread_exit();
4)计算线程设计
线程数设计:
默认情况下,计算线程数为***可用CPU核数,即SYS_CPU_CORE_NUM,用户通过宏COMPUTE_THREAD_NUM来定义计算线程数;
线程功能及运行流程:
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步聚10,否则进入步聚3;
3.检查当前任务进度COMPUTE_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤10,否则进入步聚4;
4.从新计算任务队列SR_BUF_FULL_QUEUE中获取一个任务信息tmp_msg,其包含了任务的起始信息job_begin,大小信息job_size,以及任务数据存放源缓冲编号SR_BUF_ID,并更新任务计数COMPUTE_CURRENT_STEP;
5.从DR_BUF_EMPTY_QUEUE队列中获得一个空闲的DR_BUF_ID;
6.以SR_BUF[SR_BUF_ID]为数据输入缓存,以DR_BUF[DR_BUF_ID]为数据输出缓存进行计算;
7.将SR_BUF_ID加入SR_BUF_EMPTY_QUEUE中,表示SR_BUF[SR_BUF_ID]所存的数据计算完毕,需要重新加载源数据;
8.根据计算任务信息,生成写任务信息,并将其加入到DR_BUF_FULL_QUEUE队列中,表示需要写线程进行输出;
9.返回步骤2;
10.线程退出;
线程伪代码
1)INIT
2)WHILE State_Flag && !wasCancelled
3)IF COMPUTE_CURRENT_STEP <= Total_Step
4)tmp_msg=SR_BUF_FULL_QUEUE.pop()
5)job_begin=tmp_msg.job_begin;
6)job_size=tmp_msg.job_size;
7)SR_BUF_id =tmp_msg.buf_id;
8)COMPUTE_CURRENT_STEP+=job_size;
9)tmp_msg= DR_BUF_EMPTY_QUEUE.pop();
10) DR_BUF_id =tmp_msg.buf_id;
11)COMPUTE(INPUT_FILE,SR_BUF[SR_BUF_id],DR_BUF[DR_BUF_id])
12)tmp_msg(-1,-1,SR_BUF_id);
13) SR_BUF_EMPTY_QUEUE.push(tmp_msg);
14) tmp_msg(job_begin,job_size,DR_BUF_id);
15) DR_BUF_FULL_QUEUE.push(tmp_msg);
16) ELSE
17) pthread_exit();
18)ENDIF
19)DONE
20)pthread_exit();
4)写线程设计
(1)线程数设计
根据实际应用需求,灵活设置写线程数,默认只设置一个写线程;
(2)线程功能及运行流程
1.参数初始化;
2.检查错误标志及用户行为,如果出错或被用户取消,则进入步骤9,否则进入步聚3;
3.检查当前任务进度WRITE_CURRENT_STEP,判断是否完成所有读任务,如果是,则进入步骤9,否则进入步聚4;
4.从新写任务队列DR_BUF_FULL_QUEUE中获取一个写任务信息tmp_msg,其包含了任务的起始信息job_begin,大小信息job_size,以及任务数据存放目标缓冲编号DR_BUF_ID,并更新任务计数WRITE_CURRENT_STEP;
5.将目标缓存DR_BUF[DR_BUF_ID]中的数据输出至OUTPUT_FILE;
6.将DR_BUF_ID加入DR_BUF_EMPTY_QUEUE中,表示DR_BUF[DR_BUF_ID]所存的数据输出完毕,需要重新加载计算结果;
7.向主线程发送更新进度条信号;
8.返回步骤2;
9.线程退出;
(4)线程伪代码
1.INIT
2.WHILE State_Flag && !wasCancelled
3.IF WRITE_CURRENT_STEP <= Total_Step
4.tmp_msg = DR_BUF_FULL_QUEUE.pop();
5.job_begin=tmp_msg.job_begin;
6.job_size=tmp_msg.job_size;
7.DR_BUF_id=tmp_msg.buf_id;
8.WRITE_CURRENT_STEP+=job_size;
9.WRITE(OUTPUT_FILE,DR_BUF[DR_BUF_id])
10.tmp_msg(-1,-1,DR_BUF_id);
11.DR_BUF_EMPTY_QUEUE.push(tmp_msg);
12.SEM_POST (progress_sem);
13.ELSE
14.pthread_exit();
15.ENDIF
16.DONE
17.pthread_exit()。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210316211.7A CN102902512B (zh) | 2012-08-31 | 2012-08-31 | 一种基于多线程编程及消息队列的多线程并行处理方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210316211.7A CN102902512B (zh) | 2012-08-31 | 2012-08-31 | 一种基于多线程编程及消息队列的多线程并行处理方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN102902512A true CN102902512A (zh) | 2013-01-30 |
CN102902512B CN102902512B (zh) | 2015-12-16 |
Family
ID=47574761
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201210316211.7A Active CN102902512B (zh) | 2012-08-31 | 2012-08-31 | 一种基于多线程编程及消息队列的多线程并行处理方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN102902512B (zh) |
Cited By (39)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102981805A (zh) * | 2012-11-02 | 2013-03-20 | 浪潮(北京)电子信息产业有限公司 | 串行软件的响应方法和*** |
CN103345385A (zh) * | 2013-07-29 | 2013-10-09 | 北京汉邦高科数字技术股份有限公司 | 一种串行事件转换成并行事件的方法 |
CN103543988A (zh) * | 2013-10-23 | 2014-01-29 | 华为终端有限公司 | 队列消息的处理方法、控制消息进入队列的方法及装置 |
CN103605572A (zh) * | 2013-12-05 | 2014-02-26 | 用友软件股份有限公司 | 一种多线程计算装置 |
CN103984235A (zh) * | 2014-05-27 | 2014-08-13 | 湖南大学 | 基于c/s结构的空间机械臂控制***软件架构及构建方法 |
CN104572290A (zh) * | 2013-10-11 | 2015-04-29 | 中兴通讯股份有限公司 | 消息处理线程的控制方法及装置 |
CN104572106A (zh) * | 2015-01-12 | 2015-04-29 | 浪潮电子信息产业股份有限公司 | 一种基于小内存处理大规模数据的并行程序开发方法 |
CN104572262A (zh) * | 2014-12-27 | 2015-04-29 | 北京奇虎科技有限公司 | 一种任务执行方法和装置 |
CN104798045A (zh) * | 2013-02-28 | 2015-07-22 | 甲骨文国际公司 | 用于在并行优先级队列中使用定序器的***和方法 |
CN104798044A (zh) * | 2013-02-28 | 2015-07-22 | 甲骨文国际公司 | 用于在中间件机器环境中支持协同并发性的***和方法 |
CN104821924A (zh) * | 2014-01-30 | 2015-08-05 | 西门子公司 | 一种网络数据包处理方法、装置和网络处理设备 |
CN105045632A (zh) * | 2015-08-10 | 2015-11-11 | 京信通信技术(广州)有限公司 | 一种多核环境下实现免锁队列的方法和设备 |
WO2016034138A1 (zh) * | 2014-09-05 | 2016-03-10 | 南京华讯方舟通信设备有限公司 | 基于多核、多线程实现ap和sta的接入方法 |
CN105653203A (zh) * | 2015-12-23 | 2016-06-08 | 北京奇虎科技有限公司 | 数据指令处理方法、装置及*** |
CN106133694A (zh) * | 2014-03-27 | 2016-11-16 | 国际商业机器公司 | 多线程的动态启用 |
CN106598726A (zh) * | 2016-11-04 | 2017-04-26 | 厦门安胜网络科技有限公司 | 一种多任务管理***及其分布式部署方法 |
CN106708614A (zh) * | 2016-11-21 | 2017-05-24 | 桂林远望智能通信科技有限公司 | 多线程创建***及方法、多线程处理***及方法 |
CN107153527A (zh) * | 2017-05-17 | 2017-09-12 | 北京环境特性研究所 | 一种基于消息队列的并行雷达数据处理方法 |
WO2017162059A1 (zh) * | 2016-03-23 | 2017-09-28 | 阿里巴巴集团控股有限公司 | 消息管理方法及装置、消息预读方法及装置 |
CN107273542A (zh) * | 2017-07-06 | 2017-10-20 | 华泰证券股份有限公司 | 高并发数据同步方法及*** |
CN107301087A (zh) * | 2017-06-28 | 2017-10-27 | 郑州云海信息技术有限公司 | 一种多线程***的性能提升方法和装置 |
CN107544855A (zh) * | 2017-10-11 | 2018-01-05 | 江苏电力信息技术有限公司 | 一种利用多线程快速分析处理和分发数据的方法 |
CN107908471A (zh) * | 2017-09-26 | 2018-04-13 | 聚好看科技股份有限公司 | 一种任务并行处理方法和处理*** |
CN108021597A (zh) * | 2016-10-28 | 2018-05-11 | 阿里巴巴集团控股有限公司 | 一种并行计数器、服务器和一种计数方法 |
CN108121792A (zh) * | 2017-12-20 | 2018-06-05 | 第四范式(北京)技术有限公司 | 基于任务并行处理数据流的方法、装置、设备及存储介质 |
CN108874511A (zh) * | 2018-06-15 | 2018-11-23 | 国家电网公司东北分部 | 一种基于微线程技术的通信服务快速响应*** |
CN109284193A (zh) * | 2018-09-06 | 2019-01-29 | 平安科技(深圳)有限公司 | 一种基于多线程的分布式数据处理方法及服务器 |
CN109379605A (zh) * | 2018-09-29 | 2019-02-22 | 武汉斗鱼网络科技有限公司 | 基于弹幕顺序的弹幕分发方法、装置、设备和存储介质 |
CN109413489A (zh) * | 2018-09-29 | 2019-03-01 | 武汉斗鱼网络科技有限公司 | 串行式的多线程弹幕分发方法、装置、设备和存储介质 |
CN109636309A (zh) * | 2018-11-01 | 2019-04-16 | 北京慧流科技有限公司 | 任务处理方法及装置、电子设备及存储介质 |
CN109803732A (zh) * | 2016-06-30 | 2019-05-24 | 阿果布瑞克斯有限公司 | 3d多线程参数分层有形编程接口 |
CN111008157A (zh) * | 2019-11-29 | 2020-04-14 | 北京浪潮数据技术有限公司 | 存储***写缓存数据下发方法及相关组件 |
CN111078289A (zh) * | 2017-12-04 | 2020-04-28 | 北京磐易科技有限公司 | 用于执行多线程***的子线程的方法和多线程*** |
CN112104403A (zh) * | 2020-07-21 | 2020-12-18 | 中国资源卫星应用中心 | 基于消息队列的多线程遥感卫星基带数据处理方法及装置 |
CN112415307A (zh) * | 2020-11-03 | 2021-02-26 | 北京机电工程研究所 | 一种用于并行测试的ats仪器资源控制方法 |
CN112529720A (zh) * | 2020-12-28 | 2021-03-19 | 深轻(上海)科技有限公司 | 一种寿险精算模型计算结果的汇总方法 |
CN113155851A (zh) * | 2021-04-30 | 2021-07-23 | 西安交通大学 | 基于深度学习的覆铜板表面缺陷视觉在线检测方法及装置 |
CN113901141A (zh) * | 2021-10-11 | 2022-01-07 | 京信数据科技有限公司 | 一种分布式数据同步方法及*** |
WO2022041876A1 (zh) * | 2020-08-28 | 2022-03-03 | 华为技术有限公司 | 数据传输的方法和*** |
Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101840312A (zh) * | 2009-12-31 | 2010-09-22 | 创新科存储技术有限公司 | 一种用于多核处理器的raid5写数据方法及装置 |
CN101894046A (zh) * | 2009-07-27 | 2010-11-24 | 浪潮电子信息产业股份有限公司 | 一种应用软件最优化运行方案的寻找方法 |
CN102193830A (zh) * | 2010-03-12 | 2011-09-21 | 复旦大学 | 面向众核环境的分治映射/归约并行编程模型 |
WO2012037168A2 (en) * | 2010-09-13 | 2012-03-22 | Massively Parallel Technologies, Inc. | Software design and automatic coding for parallel computing |
CN102508643A (zh) * | 2011-11-16 | 2012-06-20 | 刘大可 | 一种多核并行数字信号处理器及并行指令集的运行方法 |
-
2012
- 2012-08-31 CN CN201210316211.7A patent/CN102902512B/zh active Active
Patent Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101894046A (zh) * | 2009-07-27 | 2010-11-24 | 浪潮电子信息产业股份有限公司 | 一种应用软件最优化运行方案的寻找方法 |
CN101840312A (zh) * | 2009-12-31 | 2010-09-22 | 创新科存储技术有限公司 | 一种用于多核处理器的raid5写数据方法及装置 |
CN102193830A (zh) * | 2010-03-12 | 2011-09-21 | 复旦大学 | 面向众核环境的分治映射/归约并行编程模型 |
WO2012037168A2 (en) * | 2010-09-13 | 2012-03-22 | Massively Parallel Technologies, Inc. | Software design and automatic coding for parallel computing |
CN102508643A (zh) * | 2011-11-16 | 2012-06-20 | 刘大可 | 一种多核并行数字信号处理器及并行指令集的运行方法 |
Cited By (61)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102981805B (zh) * | 2012-11-02 | 2015-11-18 | 浪潮(北京)电子信息产业有限公司 | 串行软件的响应方法和*** |
CN102981805A (zh) * | 2012-11-02 | 2013-03-20 | 浪潮(北京)电子信息产业有限公司 | 串行软件的响应方法和*** |
CN104798045A (zh) * | 2013-02-28 | 2015-07-22 | 甲骨文国际公司 | 用于在并行优先级队列中使用定序器的***和方法 |
CN104798044A (zh) * | 2013-02-28 | 2015-07-22 | 甲骨文国际公司 | 用于在中间件机器环境中支持协同并发性的***和方法 |
CN104798044B (zh) * | 2013-02-28 | 2018-07-31 | 甲骨文国际公司 | 用于在中间件机器环境中支持协同并发性的***和方法 |
CN104798045B (zh) * | 2013-02-28 | 2018-10-16 | 甲骨文国际公司 | 用于在并行优先级队列中使用定序器的***和方法 |
CN103345385A (zh) * | 2013-07-29 | 2013-10-09 | 北京汉邦高科数字技术股份有限公司 | 一种串行事件转换成并行事件的方法 |
CN104572290A (zh) * | 2013-10-11 | 2015-04-29 | 中兴通讯股份有限公司 | 消息处理线程的控制方法及装置 |
CN103543988A (zh) * | 2013-10-23 | 2014-01-29 | 华为终端有限公司 | 队列消息的处理方法、控制消息进入队列的方法及装置 |
CN103543988B (zh) * | 2013-10-23 | 2017-05-10 | 华为终端有限公司 | 队列消息的处理方法、控制消息进入队列的方法及装置 |
CN103605572A (zh) * | 2013-12-05 | 2014-02-26 | 用友软件股份有限公司 | 一种多线程计算装置 |
CN104821924A (zh) * | 2014-01-30 | 2015-08-05 | 西门子公司 | 一种网络数据包处理方法、装置和网络处理设备 |
CN104821924B (zh) * | 2014-01-30 | 2018-11-27 | 西门子公司 | 一种网络数据包处理方法、装置和网络处理设备 |
CN106133694B (zh) * | 2014-03-27 | 2019-05-17 | 国际商业机器公司 | 一种用于配置中的多线程的动态启用的计算机实施的方法、计算机***及计算机可读介质 |
CN106133694A (zh) * | 2014-03-27 | 2016-11-16 | 国际商业机器公司 | 多线程的动态启用 |
CN103984235B (zh) * | 2014-05-27 | 2016-05-11 | 湖南大学 | 基于c/s结构的空间机械臂控制***软件架构及构建方法 |
CN103984235A (zh) * | 2014-05-27 | 2014-08-13 | 湖南大学 | 基于c/s结构的空间机械臂控制***软件架构及构建方法 |
WO2016034138A1 (zh) * | 2014-09-05 | 2016-03-10 | 南京华讯方舟通信设备有限公司 | 基于多核、多线程实现ap和sta的接入方法 |
CN104572262B (zh) * | 2014-12-27 | 2018-09-04 | 北京奇虎科技有限公司 | 一种任务执行方法和装置 |
CN104572262A (zh) * | 2014-12-27 | 2015-04-29 | 北京奇虎科技有限公司 | 一种任务执行方法和装置 |
CN104572106A (zh) * | 2015-01-12 | 2015-04-29 | 浪潮电子信息产业股份有限公司 | 一种基于小内存处理大规模数据的并行程序开发方法 |
CN105045632A (zh) * | 2015-08-10 | 2015-11-11 | 京信通信技术(广州)有限公司 | 一种多核环境下实现免锁队列的方法和设备 |
CN105653203B (zh) * | 2015-12-23 | 2019-06-07 | 北京奇虎科技有限公司 | 数据指令处理方法、装置及*** |
CN105653203A (zh) * | 2015-12-23 | 2016-06-08 | 北京奇虎科技有限公司 | 数据指令处理方法、装置及*** |
WO2017162059A1 (zh) * | 2016-03-23 | 2017-09-28 | 阿里巴巴集团控股有限公司 | 消息管理方法及装置、消息预读方法及装置 |
US11165740B2 (en) | 2016-03-23 | 2021-11-02 | Alibaba Group Holding Limited | Message sending method and terminal device |
CN109803732A (zh) * | 2016-06-30 | 2019-05-24 | 阿果布瑞克斯有限公司 | 3d多线程参数分层有形编程接口 |
CN108021597B (zh) * | 2016-10-28 | 2022-02-08 | 阿里巴巴集团控股有限公司 | 一种并行计数器、服务器和一种计数方法 |
CN108021597A (zh) * | 2016-10-28 | 2018-05-11 | 阿里巴巴集团控股有限公司 | 一种并行计数器、服务器和一种计数方法 |
CN106598726A (zh) * | 2016-11-04 | 2017-04-26 | 厦门安胜网络科技有限公司 | 一种多任务管理***及其分布式部署方法 |
CN106708614B (zh) * | 2016-11-21 | 2019-12-10 | 桂林远望智能通信科技有限公司 | 多线程创建***及方法、多线程处理***及方法 |
CN106708614A (zh) * | 2016-11-21 | 2017-05-24 | 桂林远望智能通信科技有限公司 | 多线程创建***及方法、多线程处理***及方法 |
CN107153527A (zh) * | 2017-05-17 | 2017-09-12 | 北京环境特性研究所 | 一种基于消息队列的并行雷达数据处理方法 |
CN107301087A (zh) * | 2017-06-28 | 2017-10-27 | 郑州云海信息技术有限公司 | 一种多线程***的性能提升方法和装置 |
CN107273542A (zh) * | 2017-07-06 | 2017-10-20 | 华泰证券股份有限公司 | 高并发数据同步方法及*** |
CN107273542B (zh) * | 2017-07-06 | 2020-11-27 | 华泰证券股份有限公司 | 高并发数据同步方法及*** |
CN107908471B (zh) * | 2017-09-26 | 2021-06-08 | 聚好看科技股份有限公司 | 一种任务并行处理方法和处理*** |
CN107908471A (zh) * | 2017-09-26 | 2018-04-13 | 聚好看科技股份有限公司 | 一种任务并行处理方法和处理*** |
CN107544855A (zh) * | 2017-10-11 | 2018-01-05 | 江苏电力信息技术有限公司 | 一种利用多线程快速分析处理和分发数据的方法 |
CN111078289A (zh) * | 2017-12-04 | 2020-04-28 | 北京磐易科技有限公司 | 用于执行多线程***的子线程的方法和多线程*** |
CN111078289B (zh) * | 2017-12-04 | 2021-11-23 | 北京奕斯伟智慧技术有限公司 | 用于执行多线程***的子线程的方法和多线程*** |
CN108121792B (zh) * | 2017-12-20 | 2020-06-26 | 第四范式(北京)技术有限公司 | 基于任务并行处理数据流的方法、装置、设备及存储介质 |
CN108121792A (zh) * | 2017-12-20 | 2018-06-05 | 第四范式(北京)技术有限公司 | 基于任务并行处理数据流的方法、装置、设备及存储介质 |
CN108874511A (zh) * | 2018-06-15 | 2018-11-23 | 国家电网公司东北分部 | 一种基于微线程技术的通信服务快速响应*** |
CN109284193A (zh) * | 2018-09-06 | 2019-01-29 | 平安科技(深圳)有限公司 | 一种基于多线程的分布式数据处理方法及服务器 |
CN109284193B (zh) * | 2018-09-06 | 2022-12-09 | 平安科技(深圳)有限公司 | 一种基于多线程的分布式数据处理方法及服务器 |
CN109413489A (zh) * | 2018-09-29 | 2019-03-01 | 武汉斗鱼网络科技有限公司 | 串行式的多线程弹幕分发方法、装置、设备和存储介质 |
CN109379605B (zh) * | 2018-09-29 | 2020-10-16 | 武汉斗鱼网络科技有限公司 | 基于弹幕顺序的弹幕分发方法、装置、设备和存储介质 |
CN109413489B (zh) * | 2018-09-29 | 2021-02-02 | 武汉斗鱼网络科技有限公司 | 串行式的多线程弹幕分发方法、装置、设备和存储介质 |
CN109379605A (zh) * | 2018-09-29 | 2019-02-22 | 武汉斗鱼网络科技有限公司 | 基于弹幕顺序的弹幕分发方法、装置、设备和存储介质 |
CN109636309A (zh) * | 2018-11-01 | 2019-04-16 | 北京慧流科技有限公司 | 任务处理方法及装置、电子设备及存储介质 |
CN109636309B (zh) * | 2018-11-01 | 2021-06-15 | 北京慧流科技有限公司 | 任务处理方法及装置、电子设备及存储介质 |
CN111008157A (zh) * | 2019-11-29 | 2020-04-14 | 北京浪潮数据技术有限公司 | 存储***写缓存数据下发方法及相关组件 |
CN111008157B (zh) * | 2019-11-29 | 2022-02-18 | 北京浪潮数据技术有限公司 | 存储***写缓存数据下发方法及相关组件 |
CN112104403A (zh) * | 2020-07-21 | 2020-12-18 | 中国资源卫星应用中心 | 基于消息队列的多线程遥感卫星基带数据处理方法及装置 |
WO2022041876A1 (zh) * | 2020-08-28 | 2022-03-03 | 华为技术有限公司 | 数据传输的方法和*** |
CN112415307A (zh) * | 2020-11-03 | 2021-02-26 | 北京机电工程研究所 | 一种用于并行测试的ats仪器资源控制方法 |
CN112415307B (zh) * | 2020-11-03 | 2023-01-17 | 北京机电工程研究所 | 一种用于并行测试的ats仪器资源控制方法 |
CN112529720A (zh) * | 2020-12-28 | 2021-03-19 | 深轻(上海)科技有限公司 | 一种寿险精算模型计算结果的汇总方法 |
CN113155851A (zh) * | 2021-04-30 | 2021-07-23 | 西安交通大学 | 基于深度学习的覆铜板表面缺陷视觉在线检测方法及装置 |
CN113901141A (zh) * | 2021-10-11 | 2022-01-07 | 京信数据科技有限公司 | 一种分布式数据同步方法及*** |
Also Published As
Publication number | Publication date |
---|---|
CN102902512B (zh) | 2015-12-16 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN102902512B (zh) | 一种基于多线程编程及消息队列的多线程并行处理方法 | |
CN103049245B (zh) | 一种基于中央处理器cpu多核平台的软件性能优化方法 | |
Wang et al. | Dynamic thread block launch: A lightweight execution mechanism to support irregular applications on gpus | |
KR101839544B1 (ko) | 이종 코어의 자동 부하 균형 | |
US8813073B2 (en) | Compiling apparatus and method of a multicore device | |
CN102099789B (zh) | 多处理器的多维线程分组 | |
Huynh et al. | Scalable framework for mapping streaming applications onto multi-GPU systems | |
CN102708009B (zh) | 一种基于cuda实现多任务共享gpu的方法 | |
Tillenius et al. | Resource-aware task scheduling | |
Abdolrashidi et al. | Wireframe: Supporting data-dependent parallelism through dependency graph execution in gpus | |
CN103279391A (zh) | 一种基于cpu与mic架构处理器协同计算的负载均衡优化方法 | |
CN101833438A (zh) | 一种基于多重并行的数据通用处理方法 | |
Hu et al. | A closer look at GPGPU | |
Chen et al. | Balancing scalar and vector execution on gpu architectures | |
Zhang et al. | Optimization of N-queens solvers on graphics processors | |
Valero et al. | Towards a more efficient use of gpus | |
Zhang et al. | Design of a multithreaded Barnes-Hut algorithm for multicore clusters | |
CN103699363A (zh) | 一种用于在多核平台下优化关键临界区的方法 | |
Gijsbers et al. | An efficient scalable runtime system for macro data flow processing using S-Net | |
Garcia et al. | A dynamic schema to increase performance in many-core architectures through percolation operations | |
CN113076191A (zh) | 一种集群gpu资源调度*** | |
Dalmia et al. | Improving the Scalability of GPU Synchronization Primitives | |
CN102981805A (zh) | 串行软件的响应方法和*** | |
Rauschmayr | Optimisation of LHCb applications for multi-and manycore job submission | |
Ayuso et al. | Parallelizing a CAD model processing tool from the automotive industry |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant |