多进程编程实例
A. 嵌入式linux应用层开发有哪些实例
一:C语言 嵌入式Linux工程师的学习需要具备一定的C语言基础,C语言是嵌入式领域最重要也是最主要的编程语言,通过大量编程实例重点理解C语言的基础编程以及高级编程知识。包括:基本数据类型、数组、指针、结构体、链表、文件操作、队列、栈等。
二:Linux基础 Linux操作系统的概念、安装方法,详细了解Linux下的目录结构、基本命令、编辑器VI ,编译器GCC,调试器GDB和 Make 项目管理工具, Shell Makefile脚本编写等知识,嵌入式开发环境的搭建。
三:Linux系统编程 重点学习标准I/O库,Linux多任务编程中的多进程和多线程,以及进程间通信(pipe、FIFO、消息队列、共享内存、signal、信号量等),同步与互斥对共享资源访问控制等重要知识,主要提升对Linux应用开发的理解和代码调试的能力。
四:Linux网络编程 计算机网络在嵌入式Linux系统应用开发过程中使用非常广泛,通过Linux网络发展、TCP/IP协议、socket编程、TCP网络编程、UDP网络编程、Web编程开发等方面入手,全面了解Linux网络应用程序开发。重点学习网络编程相关API,熟练掌握TCP协议服务器的编程方法和并发服务器的实现,了解HTTP协议及其实现方法,熟悉UDP广播、多播的原理及编程方法,掌握混合C/S架构网络通信系统的设计,熟悉HTML,javascript等Web编程技术及实现方法。
五:数据结构与算法 数据结构及算法在嵌入式底层驱动、通信协议、及各种引擎开发中会得到大量应用,对其掌握的好坏直接影响程序的效率、简洁及健壮性。此阶段的学习要重点理解数据结构与算法的基础内容,包括顺序表、链表、队列、栈、树、图、哈希表、各种查找排序算法等应用及其C语言实现过程。
六:C++ 、QT C++是Linux应用开发主要语言之一,本阶段重点掌握面向对象编程的基本思想以及C++的重要内容。图形界面编程是嵌入式开发中非常重要的一个环节。由于QT具有跨平台、面向对象、丰富API、支持2D/3D渲染、支持XML、多国语等强大功能,在嵌入式领域的GUI开发中得到了广范的应用,在本阶段通过基于QT图形库的学习使学员可以熟练编写GUI程序,并移植QT应用程序到Cortex-A8平台。包括IDE使用、QT部件及布局管理器、信息与槽机制的应用、鼠标、键盘及绘图事件处理及文件处理的应用。
七:Cortex A8 、Linux 平台开发 通过基于ARM Cortex-A8处理s5pv210了解芯片手册的基本阅读技巧,掌握s5pv210系统资源、时钟控制器、电源管理、异常中断控制器、nand flash控制器等模块,为底层平台搭建做好准备。Linux平台包括内核裁减、内核移植、交叉编译、GNU工具使用、内核调试、Bootloader介绍、制作与原理分析、根文件系统制作以及向内核中添加自己的模块,并在s5pv210实验平台上运行自己制作的Linux系统,集成部署Linux系统整个流程。同时了解Android操作系统开发流程。Android系统是基于Linux平台的开源操作系统,该平台由操作系统、中间件、用户界面和应用软件组成,是首个为移动终端打造的真正开放和完整的移动软件,目前它的应用不再局限于移动终端,还包括数据电视、机顶盒、PDA等消费类电子产品。
八:驱动开发 驱动程序设计是嵌入式Linux开发工作中重要的一部分,也是比较困难的一部分。本阶段的学习要熟悉Linux的内核机制、驱动程序与用户级应用程序的接口,掌握系统对设备的并发操作。熟悉所开发硬件的工作原理,具备ARM硬件接口的基础知识,熟悉ARM Cortex-A8处理器s5pv210各资源、掌握Linux设备驱动原理框架,熟悉工程中常见Linux高级字符设备、块设备、网络设备、USB设备等驱动开发,在工作中能独立胜任底层驱动开发。
以上就是列出的关于一名合格嵌入式Linux开发工程师所必学的理论知识,其实,作为一个嵌入式开发人员,专业知识和项目经验同样重要,所以在我们的理论学习中也要有一定的项目实践,锻炼自己的项目开发能力。
B. 并发编程数据共享有哪几种机制如何保证数据同步
1、多进程并发
在传统UNIX中较常用,针对每一种单独的业务逻辑的实例生成不同的线程进行处理。典型的程序实例是针对TCP的多个不同的客户端连接,fork出多个子进程进行处理,每一个客户端对应一个单独的子进程,在子进程处理退出后,由父进程回收其资源。
优点:各进程间的地址空间相互隔离,不会因为某些不当操作将整个应用搞挂。
业务逻辑代码简单清晰,代码平铺直叙,没有复杂的异步状态逻辑。
缺点:如果需要在进程间进行交互或者共享数据,需要使用IPC。
2、多线程并发
在现代操作系统windows、linux中很常用,针对单独的业务逻辑的不同的实例在同一个进程中创建多个线程进行并发处理。典型的例子是,TCP的多个客户端在同一个进程中处理,针对每个客户端都单独对应的线程进行交互,共享同一个进程的所有资源。
优点:共享进程空间,访问共享数据非常容易。
没有多的进程空间开销,线程上下文切换快,调度效率比多进程高。
业务逻辑代码简单清晰,代码平铺直叙,没有复杂的异步状态逻辑。
缺点:维护线程的工作由进程内部代码处理,比如线程数量,增加一定的复杂性。
线程间共享数据的竞争关系复杂,需要处理同步和死锁问题。
3、IO多路复用
即在单线程控制多个异步业务逻辑,也就是事件驱动多个业务的状态处理,典型的有windows中的消息处理机制,还有linux中的信号量处理。可以在单一线程中,处理多种不同的业务逻辑,比如同时处理用户输出,鼠标点击,窗口重绘和网络输入。
优点:所有业务实例的逻辑在单一线程中处理,排除代码时序BUG,理论上不存在竞争和死锁问题。
没有多的进程空间开销,也没有上下文切换问题,CPU利用率高。
共享进程空间,访问共享数据非常容易。
缺点:
线程需要管理多个不同实例的状态机,并正确处理对应事件导致不同状态的迁移。
业务种类多的情况下,需要人为代码控制多种状态机。
并发点越多造成状态越多,管理粒度越细, 业务逻辑代码不是顺序的,不容易维护和理解。
异步状态过多,造成资源管理较为复杂,容易产生资源泄漏。
C. 什么是java多线程详解
线程对象是可以产生线程的对象。比如在Java平台中Thread对象,Runnable对象。线程,是指正在执行的一个指点令序列。在java平台上是指从一个线程对象的start()开始,运行run方法体中的那一段相对独立的过程。相比于多进程,多线程的优势有:
(1)进程之间不能共享数据,线程可以;
(2)系统创建进程需要为该进程重新分配系统资源,故创建线程代价比较小;
(3)Java语言内置了多线程功能支持,简化了java多线程编程。
一、创建线程和启动
(1)继承Thread类创建线程类
通过继承Thread类创建线程类的具体步骤和具体代码如下:
• 定义一个继承Thread类的子类,并重写该类的run()方法;
• 创建Thread子类的实例,即创建了线程对象;
• 调用该线程对象的start()方法启动线程。
复制代码
class SomeThead extends Thraad {
public void run() {
//do something here
}
}
public static void main(String[] args){
SomeThread oneThread = new SomeThread();
步骤3:启动线程:
oneThread.start();
}
复制代码
(2)实现Runnable接口创建线程类
通过实现Runnable接口创建线程类的具体步骤和具体代码如下:
• 定义Runnable接口的实现类,并重写该接口的run()方法;
• 创建Runnable实现类的实例,并以此实例作为Thread的target对象,即该Thread对象才是真正的线程对象。
复制代码
class SomeRunnable implements Runnable {
public void run() {
//do something here
}
}
Runnable oneRunnable = new SomeRunnable();
Thread oneThread = new Thread(oneRunnable);
oneThread.start();
复制代码
(3)通过Callable和Future创建线程
通过Callable和Future创建线程的具体步骤和具体代码如下:
• 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
• 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
• 使用FutureTask对象作为Thread对象的target创建并启动新线程。
• 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值其中,Callable接口(也只有一个方法)定义如下:
复制代码
public interface Callable {
V call() throws Exception;
}
步骤1:创建实现Callable接口的类SomeCallable(略);
步骤2:创建一个类对象:
Callable oneCallable = new SomeCallable();
步骤3:由Callable创建一个FutureTask对象:
FutureTask oneTask = new FutureTask(oneCallable);
注释: FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了 Future和Runnable接口。
步骤4:由FutureTask创建一个Thread对象:
Thread oneThread = new Thread(oneTask);
步骤5:启动线程:
oneThread.start();
D. 一个进程通信 的 linux程序编写
学习步骤如下:
1、Linux 基础
安装Linux操作系统
Linux文件系统
Linux常用命令
Linux启动过程详解
熟悉Linux服务能够独立安装Linux操作系统
能够熟练使用Linux系统的基本命令
认识Linux系统的常用服务安装Linux操作系统
Linux基本命令实践
设置Linux环境变量
定制Linux的服务 Shell 编程基础使用vi编辑文件
使用Emacs编辑文件
使用其他编辑器
2、Shell 编程基础
Shell简介
认识后台程序
Bash编程熟悉Linux系统下的编辑环境
熟悉Linux下的各种Shell
熟练进行shell编程熟悉vi基本操作
熟悉Emacs的基本操作
比较不同shell的区别
编写一个测试服务器是否连通的shell脚本程序
编写一个查看进程是否存在的shell脚本程序
编写一个带有循环语句的shell脚本程序
3、Linux 下的 C 编程基础
linux C语言环境概述
Gcc使用方法
Gdb调试技术
Autoconf
Automake
Makefile
代码优化 熟悉Linux系统下的开发环境
熟悉Gcc编译器
熟悉Makefile规则编写Hello,World程序
使用 make命令编译程序
编写带有一个循环的程序
调试一个有问题的程序
4、嵌入式系统开发基础
嵌入式系统概述
交叉编译
配置TFTP服务
配置NFS服务
下载Bootloader和内核
嵌入式Linux应用软件开发流程
熟悉嵌入式系统概念以及开发流程
建立嵌入式系统开发环境制作cross_gcc工具链
编译并下载U-boot
编译并下载Linux内核
编译并下载Linux应用程序
嵌入式系统移植
Linux内核代码
平台相关代码分析
ARM平台介绍
平台移植的关键技术
移植Linux内核到 ARM平台 了解移植的概念
能够移植Linux内核移植Linux2.6内核到 ARM9开发板
5、嵌入式 Linux 下串口通信
串行I/O的基本概念
嵌入式Linux应用软件开发流程
Linux系统的文件和设备
与文件相关的系统调用
配置超级终端和MiniCOM 能够熟悉进行串口通信
熟悉文件I/O 编写串口通信程序
编写多串口通信程序
6、嵌入式系统中多进程程序设计
Linux系统进程概述
嵌入式系统的进程特点
进程操作
守护进程
相关的系统调用了解Linux系统中进程的概念
能够编写多进程程序编写多进程程序
编写一个守护进程程序
sleep系统调用任务管理、同步与通信 Linux任务概述
任务调度
管道
信号
共享内存
任务管理 API 了解Linux系统任务管理机制
熟悉进程间通信的几种方式
熟悉嵌入式Linux中的任务间同步与通信
编写一个简单的管道程序实现文件传输
编写一个使用共享内存的程序
7、嵌入式系统中多线程程序设计
线程的基础知识
多线程编程方法
线程应用中的同步问题了解线程的概念
能够编写简单的多线程程序编写一个多线程程序
8、嵌入式 Linux 网络编程
网络基础知识
嵌入式Linux中TCP/IP网络结构
socket 编程
常用 API函数
分析Ping命令的实现
基本UDP套接口编程
许可证管理
PPP协议
GPRS 了解嵌入式Linux网络体系结构
能够进行嵌入式Linux环境下的socket 编程
熟悉UDP协议、PPP协议
熟悉GPRS 使用socket 编写代理服务器
使用socket 编写路由器
编写许可证服务器
指出TCP和UDP的优缺点
编写一个web服务器
编写一个运行在 ARM平台的网络播放器
9、GUI 程序开发
GUI基础
嵌入式系统GUI类型
编译QT
进行QT开发熟悉嵌入式系统常用的GUI
能够进行QT编程使用QT编写“Hello,World”程序
调试一个加入信号/槽的实例
通过重载QWidget 类方法处理事件
10、Linux 字符设备驱动程序
设备驱动程序基础知识
Linux系统的模块
字符设备驱动分析
fs_operation结构
加载驱动程序了解设备驱动程序的概念
了解Linux字符设备驱动程序结构
能够编写字符设备驱动程序编写Skull驱动
编写键盘驱动
编写I/O驱动
分析一个看门狗驱动程序
对比Linux2.6内核与2.4内核中字符设备驱动的不同
Linux 块设备驱动程序块设备驱动程序工作原理
典型的块设备驱动程序分析
块设备的读写请求队列了解Linux块设备驱动程序结构
能够编写简单的块设备驱动程序比较字符设备与块设备的异同
编写MMC卡驱动程序
分析一个文件系统
对比Linux2.6内核与2.4内核中块设备驱动的不同
11、文件系统
虚拟文件系统
文件系统的建立
ramfs内存文件系统
proc文件系统
devfs 文件系统
MTD技术简介
MTD块设备初始化
MTD块设备的读写操作了解Linux系统的文件系统
了解嵌入式Linux的文件系统
了解MTD技术
能够编写简单的文件系统为 ARM9开发板添加 MTD支持
移植JFFS2文件系统
通过proc文件系统修改操作系统参数
分析romfs 文件系统源代码
创建一个cramfs 文件系统
E. 有什么情况一定要, 只能是多线程编程才能解决 给个具体的例子, 我初学多线程...
这是典型的对多线程不理解造成的,问题本身就存在问题。
多线程只是一种技术——所以没有所谓的必须,或是只能。
多线程有其自己的适用范围,我们只能说在哪种情况下适合使用多线程,但这种情况下绝对不会是只有多线程能解决。所以问题就言是多线程的典型应用场景,而非这么绝对的问一定要,只能是!不信换一种结构——比如阵列处理器,人家编程时就使用了阵列,与线程的概念就没有任何关系不了!
典型的使用场景其就是一个:充分利用IO资源。
比如说一个界面在工作时不停地接收输入信息(如键盘,mouse,网卡等)而界面或是程序对信息处理时间较长时,最好使用多线程,多线程的意义在于在CPU参于界面处理的同时,可以处理输入事件。如果单线程,你必须等待界面或是程序处理完成之后才可以处理输入事件,而多线程为了防止这种界面或是程序假死的现象(单线程在处理界面时不接受事件)。
再者如果程序在运行过程中,由于要长时间地硬盘进行读写,那么多线程也能很好地解决这一问题。
其实它的目的就是研究发现:单线程(进程)在CPU工作时可能造成其他IO资源(如磁盘IO)的空闲,而使用多线程则是合理利用IO资源,加快整个软件的运行。
事实上了,windows系统是一个多任务多进程的工作,每个进程之间利用的是CPU时间轮片法。而线程之间则利用的多资源的同步进行。
所以说,多线程本身只是提高了IO利用率,与长时间处理什么的其实也没有多大关系。比如windows服务并非线程,但每个windows服务是一个进程,为什么还都可以同时并发在系统中?这个原因就是CPU轮片。而多线程是基于进程所占cpu时间片内的IO资源充分利用。
另一个技术也是线程延伸,就是我们常说的CPU是四核八线,其实他只是将每个物理核心再虚拟一个线程CPU,只不过这个所谓的四核八线CPU仅仅只是提高了CPU的利用率而已。
笑一楼与二楼,还扯什么消息机制——这与系统与毛关系?都是大神啊!
其实在单核单线的CPU上,多线程除了增加线程开辟与回收等开销外,对于CPU并不占任何便宜。而多进程之间已经有CPU轮片法进行各进程的统筹了。
F. vc怎么调用ansys
ANSYS基于VC++6.0的二次开发与
相互作用分析在ANSYS中的实现
1 概述
ANSYS是一套功能十分强大的有限元分析软件,能实现多场及多场耦合分析;是实现前后处理、求解及多场分析统一数据库的一体化大型FEA软件;支持异种、异构平台的网络浮动,在异种、异构平台上用户界面统一、数据文件全部兼容,强大的并行计算功能支持分布式并行及共享内存式并行。该软件具有如下特点:
(1) 完备的前处理功能
ANSYS不仅提供了强大的实体建模及网格划分工具,可以方便地构造数学模型,而且还专门设有用户所熟悉的一些大型通用有限元软件的数据接口(如MSC/NSSTRAN,ALGOR,ABAQUS等),并允许从这些程序中读取有限元模型数据,甚至材料特性和边界条件,完成ANSYS中的初步建模工作。此外,ANSYS还具有近200种单元类型,这些丰富的单元特性能使用户方便而准确地构建出反映实际结构的仿真计算模型。
(2) 强大的求解器
ANSYS提供了对各种物理场量的分析,是目前唯一能融结构、热、电磁、流体、声学等为一体的有限元软件。除了常规的线性、非线性结构静力、动力分析外,还可以解决高度非线性结构的动力分析、结构非线性及非线性屈曲分析。提供的多种求解器分别适用于不同的问题及不同的硬件配置。
(3) 方便的后处理器
ANSYS的后处理分为通用后处理模块(POST1)和时间历程后处理模块(POST26)两部分。后处理结果可能包括位移、温度、应力、应变、速度以及热流等,输出形式可以有图形显示和数据列表两种。
(4) 多种实用的二次开发工具
ANSYS除了具有较为完善的分析功能外,同时还为用户进行二次开发提供了多种实用工具。如宏(Marco)、参数设计语言(APDL)、用户界面设计语言(UIDL)及用户编程特性(UPFs),其中APDL(ANSYS Parametric Design Language)是一种非常类似于Fortran77的参数化设计解释性语言,其核心内容为宏、参数、循环命令和条件语句,可以通过建立参数化模型来自动完成一些通用性强的任务;UIDL(User Interface Design Language)是ANSYS为用户提供专门进行程序界面设计的语言,允许用户改变ANSYS的图形用户界面(GUI)中的一些组项,提供了一种允许用户灵活使用、按个人喜好来组织设计ANSYS图形用户界面的强有力工具;UPFs(User Programmable Features)提供了一套Fortran77函数和例程以扩展或修改程序的功能,该项技术充分显示了ANSYS的开放体系,用户不仅可以采用它将ANSYS程序剪裁成符合自己所需的任何组织形式(如可以定义一种新的材料,一个新的单元或者给出一种新的屈服准则),而且还可以编写自己的优化算法,通过将整个ANSYS作为一个子程序调用的方式实现。
鉴于上述特点,近几年来,ANSYS软件在国内外工程建设和科学研究中得到了广泛的应用。但这些应用大多局限于直接运用ANSYS软件进行实际工程分析,对利用ANSYS提供的二次开发工具进行有限元软件设计却很少涉及。本文首次利用ANSYS软件的二次开发功能,以VC++6.0为工具,运用APDL语言,对ANSYS进行二次开发,编制框筒结构-桩筏基础-土相互作用体系与地震反应分析程序。
2 程序设计目标
针对某一实际工程问题,ANSYS所提供的APDL语言可对ANSYS软件进行封装。APDL语言即ANSYS软件提供的参数化设计语言,它的全称是ANSYS Parametric Design Language。 使用APDL语言可以更加有效地进行分析计算,可以轻松地进行自动化工作(循环、分支、宏等结构),而且,它是一种高效的参数化建模手段。使用APDL语言进行封装的系统可以只要求操作人员输入前处理参数,然后自动运行ANSYS进行求解。但完全用APDL编写的宏还存在弱点。比如用APDL语言较难控制程序的进程,虽然它提供了循环语句和条件判断语句,但总的来说还是难以用来编写结构清晰的程序。它虽然提供了参数的界面输入,但功能还不是太强,交互性不够流畅。针对这种情况,本文用VC++6.0开发框筒结构-桩筏基础-土相互作用有限元分析程序(简称LWS程序)。
本程序设计目标是利用VC++6.0对ANSYS进行封装。用VC++6.0对ANSYS模拟框筒结构-桩筏基础-土相互作用进行二次开发,用户只需输入诸如地震波、计算时间步长、阻尼比等物理性能参数等,系统就能自动调用ANSYS计算程序,自动进行网格划分、地震动加载以及自动求解。该系统由于前台开发友好、方便、易用的人机交互界面,对复杂的、难于理解和掌握的ANSYS命令流进行后台封装,因此,程序设计可让即使从未认真学习过ANSYS软件的工程设计人员也能很好地借助本系统进行结构抗震性能有限元分析,具有较强的处理实际问题能力。
用户输入计算参数,即可调用后台的ANSYS命令进行计算,ANSYS把计算结果返回给用户,进行后处理。
程序设计的主要原则和功能如下:
(1)方便原则,即程序模块应具有良好的用户界面和易用性。程序前台设计采用Windows提供的标准图形用户界面(GUI),用户无须接受专门训练即可使用。同时,程序应具有良好的容错和纠错能力,避免用户操作不当造成损失。
(2)程序系统能够提供用户以下功能:
①允许用户可以根据实际计算工况,输入特定的计算参数,包括地震波选择、计算时间步长、地震波调幅与否等。
②用户在输入各种参数以后、进行计算之前可以对输入的数据进行修改、添加和删除操作,以保证输入正确的参数。
③用户通过界面调用后台的ANSYS命令流进行计算,能够得到最后的计算结果文件,供用户进行后处理和结果分析。
④用户可以添加新的功能或新的二次开发以实现程序升级。
(3)程序应具有良好的可移植性,不依赖于特定的硬件设备,只要能安装ANSYS和VC++6.0的硬件环境都能使用本系统,保证程序使用的广泛性。
(4)程序代码应具有开放性和可重用性。这样,在进一步的设计中,能保证设计者可以方便地对代码进行修改扩充;同时,提供一定的设计接口,新的设计者可以根据接口,无须对程序进行大幅度的修改,就可以进行新的开发,以适应新的特殊要求。
程序的开发平台是Microsoft VC++6.0、ANSYS6.1,基于WindowsXP编程。程序实现是利用微软提供的Windows编程接口MFC和ANSYS公司的ANSYS/Multiphysics产品,采用面向对象的程序设计方法。
3程序的主要模块和设计
如图3-2所示,程序的主要模块有:用户界面模块、ANSYS计算模块、VC调用接口模块和VC后处理模块,分别论述如下:
3.1 ANSYS模块
ANSYS为了满足用户的特殊需求,建立了开放的体系结构,提供了二次开发接口APDL、UIDL和UPFs(User Programming Features,用户编程特性)等。其中,ANSYS接口允许用户将自己的VC代码连到ANSYS中去,或将ANSYS作为子程序调用,从而使ANSYS具备特殊的功能。
本文的ANSYS模块是使用APDL语言进行二次开发的。在上面的二次开发中用到了参数化设计方法。参数是APDL的变量(它们更象FORTRAN变量,而不像FORTRAN参数),不必明确声明参数类型,所有数值变量都以双精度数存储。被使用但未声明的参数都被赋予接近0的“极小值”。在二次开发中使用参数化设计方法,增强了程序的易读性和可移植性。用户无须了解程序的具体结构只需改变参数值就可自动调用ANSYS模块。
3.2 VC调用模块
VC调用模块在该系统中起着接受用户界面的输入、创建进程调用ANSYS模块进行计算的重要作用。有两项工作是在实现在VC程序中调用ANSYS必须做的,一是要使接口程序能够修改ANSYSB的命令流文件路径及文件名称,这可通过注册表编程实现;二是要能在接口程序中运行ANSYSB应用程序,这涉及到创建进程的编程,下面分别介绍它们的具体实现。
1. 注册表编程
在Windows(98/NT/2000/XP)系统上运行ANSYS安装程序后,便在Windows系统的注册表里记录了一些信息,如初始工作路径,文件名等。利用VC平台调用ANSYS计算模块的程序必须指定ANSYS软件的运行目录以及用APDL语言开发的ANSYS模块程序路径,这样,ANSYS软件的批处理程序才能从给定的路径下读取命令流文件。在接口程序中修改这些注册表信息,可以使用Windows提供的注册表编辑API(Application Programming Interface)函数[30,31],具体实现如下:
HKEY hSubKey; // 定义子键
LONG lRet;
char RegPath[200]="SoftWare\\ANSYS, Inc.\\ANSYS\\ANSYS 6.1\\0";
lRet=RegOpenKeyEx(HKEY_CURRENT_USER,RegPath,0,KEY_ALL_ACCESS,&hSubKey); // 打开子键
if(lRet!=ERROR_SUCCESS)return;
lRet=RegSetValueEx(hSubKey,"Extension",0,REG_SZ,(LPBYTE)"txt",3); //设置ANSYS批处理程序读取的文件扩展名
if(lRet!=ERROR_SUCCESS)return;
lRet=RegSetValueEx(hSubKey,"Jobname",0,REG_SZ,(LPBYTE)"ZHY");
//指定ANSYS模块文件名
if(lRet!=ERROR_SUCCESS)return;
lRet=RegSetValueEx(hSubKey,"WorkingDirectory",0,REG_SZ,(LPBYTE)"E:\\LWS\\Workspace ",16);
if(lRet!=ERROR_SUCCESS)return; // 键值出错返回
RegCloseKey(hSubKey); // 关闭子键
通过以上的设置后运行ANSYS批处理程序,界面变成如图3-3所示。
从图中可看出ANSYS模块工作路径E:\\LWS\\Workspace、初始文件名ZHY、ANSYS程序文件名ZHY.txt文件、计算结果输出文件名ZHY.out都已经自动出现在ANSYS批处理程序的输入框,往下ANSYS就可以自动从ZHY.txt读取命令流进行计算并将结果输出到ZHY.out文件中。若想改ANSYS模块路径或文件名只需对上面程序稍加修改即可。
2. 多进程编程
本文在VC平台上对ANSYS进行封装,希望前台处理系统和用户的交互,而后台进行ANSYS的计算。这就要求系统具有并发性,为此,引入多进程编程机制。进程是一个正在运行程序的实例,它具有动态性、并发性、独立性、异步性和结构性等特点。系统中的进程动态产生与消亡,多个进程并发运行,分别执行各自对应的程序段,为各自的目标而工作。一个程序可以包含多个进程。
图3-3 ANSYS批处理运行界面
在VC++6.0中可以利用CreateProcess函数来创建一个进程去执行其他程序,而且可以设置该进程的优先级。CreateProcess函数的原型是:
BOOL CreateProcess(
LPCTSTR lpAppliciatonName
LPTSTR lpCommandLine
LPSECURITY_ATTRIBUTES lpProcessAttributes
LPSECURITY_ATTRIBUTES lpThreadAttributes
BOOL bInheritHandles
DWORD dwCreationFlags
LPVOID lpEnvironment
LPCTSTR lpCurrentDirectory
LPSTARTUPINFO lpStartupInfo
LPPROCESS_INFORMATION lpProcessInformation
);
当系统调用CreateProcess时,会创建一个进程内核对象,其初始使用计数是1。该进程内核对象不是进程本身,而是操作系统管理进程时使用的一个较小的数据结构。然后,系统为新进程创建一个虚拟地址空间,并将可执行文件或任何必要的DLL文件的代码和数据加载到该进程的地址空间中。接着,系统为新进程的主线程创建一个线程内核对象(其使用计数为1)。与进程内核对象一样,线程内核对象也是操作系统用来管理线程的小型数据结构。通过执行C/C++运行期启动代码,该主线程便开始运行,它最终调用WinMain、wWinMain、main或wmain函数。如果系统成功创建了新进程和主线程,CreateProcess便返回True。
PszApplicationName和pszCommandLine参数分别用于设定新进程将要使用的可执行文件的名字和传递给新进程的命令行字符串。PszApplicationName的参数可以是NULL,表示系统将使用全路径来查看可执行文件,并且不再搜索这些目录;如果参数不是NULL可以将地址传递给pszApplicationName参数中包含可运行的文件的名字字符串。当系统找到了可执行文件后,就创建一个新进程,并将可执行文件的代码和数据映射到新进程的地址空间中。
PsaProcess和psaThread参数分别设定进程对象和线程对象需要的安全性。可以为这些参数传递NULL,这种情况下,系统为这些对象赋予默认安全性描述符;也可以指定两个SECURITY_ATTRIBUTES结构,并对它们进行初始化,以便创建自己的安全性权限,并将它们赋予进程对象和线程对象。将SECRURITY_ATTRIBUTES 结构用于psaProcess和psaThread参数的另一个原因是,父进程将来生成的任何子进程都可以继承这两个对象句柄中的任何一个。本程序除了创键调用ANSYS计算模块的进程外,无需再创建其它进程,因而,psaProcess和psaThread参数都为NULL。同理,binheritHandles参数为FALSE。
fdwCreate参数用于标识标志,以便用于规定如何来创建新进程,fdwCreate参数也可以用来设定优先级类,不过对于大多数应用程序来说不应该这样做,因为系统会为新进程赋予一个默认优先级。
PszCurDir参数允许父进程设置子进程的当前驱动器和目录。如果本参数为NULL,则新进程的工作目录将与生成新进程的应用程序的目录相同;若不为空,则必须指向包含需要的工作驱动器和工作目录的以0结尾的字符串。课题中该参数选择为NULL就可以了。
PsiStartInfo参数用于指向一个STARTUPINFO结构。当Windows创建新进程时,它将使用该结构的有关成员。大多数应用程序将要求生成的应用程序仅仅使用默认值。至少应该将该结构中的所有成员初始化为零,然后将cb(cb为STARTUPINFO结构成员)设置为该结构的大小。STARTUPINFO结构的其他具体成员参见VC++6.0帮助系统MSDN。
PpiProcInfo参数用于指向你必须指定的PROCESS_INFORMATION结构。CreateProcess在返回之前要对该结构的成员进行初始化。该结构的形式如下面所示:
Typedef struct _PROCESS_INFORMATION{
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
}PROCESS_INFORMATION;
CreateProcess在返回之前打开进程对象和线程对象,并将每个对象的与进程相关的句柄放入PROCESS_INFORMATION结构的hProcess和hThread成员中。
综上所述,课题创建进程的关键程序如下:
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
memset(&StartupInfo,0,sizeof(STARTUPINFO)); //分配内存
StartupInfo.cb=sizeof(STARTUPINFO); // 初始化
StartupInfo.dwFlags=STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow=SW_SHOWMAXIMIZED;
if(!::CreateProcess(NULL,d:\\ProgramFiles\\Ansys
Inc\\ANSYS61\\bin\\intel\\AnsysB”,NULL,NULL,FALS E,0,NULL,NULL,&StartupInfo,&ProcessInfo))
{
AfxMessageBox("error!");
GetLastError();
} // 创建进程
3. 进程的终止
要终止进程的运行可以使用如下四种方法:①主线程的进入点函数返回;②进程中的一个线程调用ExitProcess函数;③另一个进程中的线程调用TerminateProcess函数;④所有进程中的线程自动终止运行(这种情况一般不会发生)。本文采用第一种方法终止所创建的进程,即当ANSYS计算结束时通过函数返回。
在WindowsXP系统中,如果ANSYS批处理程序运行完后,窗口标题会显示“ANSYS已完成”。本文程序开发便可通过这一特点来终止系统所创建的进程。当ANSYS计算模块运行完毕后,系统会弹出一个消息框提示ANSYS已计算完毕,可以进行后处理了。
3.3.3 用户界面接口模块
用户界面模块主要完成系统和用户的交互。用户界面模块包括计算参数输入和程序调用两部分。计算参数输入部分的主要功能是负责输入诸如地震波数据、是否调幅、时间步长等。计算输入是由对话框构成。计算参数输入对话框界面如下:
图3-4 计算参数输入界面
程序对各参数的输入范围都进行了设定,如果用户输入的参数超过了这一设定,系统就会弹出对话框以提醒用户输入错误,需要重新输入。ANSYS程序调用通过菜单方式进行。该菜单首先不处于激活状态,而是当三维数值模拟所需参数输入完成后才得到消息激活菜单。这样设计的优点:能够提醒用户输入并检查用于三维数值模拟的相关参数,避免用户在不输入参数的情况下直接调用ANSYS进行计算而造成错误。
程序设计采用文档读写的方式将输入的计算参数插入到用APDL语言进行二次开发的ANSYS计算模块。参数化设计的ANSYS计算模块就可以根据输入的参数进行数值模拟计算。
3.3.4 ANSYS后处理模块的二次开发
ANSYS软件提供了两个后处理器,可以对结果进行时间-历程后处理
和通用后处理。对于相互作用体系地震反应分析,它可以将模拟结果用应力图、等值线(面)、动画等形式输出与转换。其中POST1通用后处理器可用于观察整个模型或模型的一部分在某一时间的模拟结果,可显示结构在地震作用下的应力图和位移变形图;时间—历程后处理器POST26用于检查模型中指定点的分析结果与时间的函数关系,可显示模型上各个节点的各变量的时程曲线。可见,对于大多数的后处理分析我们可以直接使用ANSYS的后处理器。但由于ANSYS是一个通用软件,而对某些特殊领域的后处理分析无能为力或者不是很方便,因而,需要对其进行二次开发,以减轻后处理工作和提高后处理效率。
在相互作用体系地震反应分析中,有时除了关注各物理量时程曲线外,还关心其在结构高度方向的分布(如层间位移、层间剪力、层间加速度反应等)。解决这一问题的二次开发需要结合相互作用体系地震反应分析特点进行。
(1)物理量分析
在地震反应时程分析中,我们对楼层位移时程、加速度时程、柱应力应变时程 、剪力墙应力应变时程比较关心,同时还需要分析层间位移和层间加速度变化。考虑到本文将计算多种工况,本程序对常见的变量编写了后处理程序,具有通用性,极大地提高了后处理效率。
(2) 程序实现
基于上面分析,本程序是通过接口程序调用ANSYS,读入编写的后处理命令流,读取ANSYS计算的结果数据库,生成各变量的结果文件,然后用本程序的后处理模块进行读数绘图处理,进而生成结果图形。这一过程采用VC编程实现的,VC编程的算法流程图如图3-2的后处理模块。(转贴)
G. 多线程 python和多进程的区别
前面的章节,我们刚刚介绍过socket和socketserver网络编程。
在socketserver服务端代码中有这么一句:
server = socketserver.ThreadingTCPServer((ip,port), MyServer)
ThreadingTCPServer这个类是一个支持多线程和TCP协议的socketserver,它的继承关系是这样的:
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
右边的TCPServer实际上是主要的功能父类,而左边的ThreadingMixIn则是实现了多线程的类,ThreadingTCPServer自己本身则没有任何代码。
MixIn在Python的类命名中很常见,称作“混入”,戏称“乱入”,通常为了某种重要功能被子类继承。
我们看看一下ThreadingMixIn的源代码:
class ThreadingMixIn:
daemon_threads = False
def process_request_thread(self, request, client_address):
try:
self.finish_request(request, client_address)
self.shutdown_request(request)
except:
self.handle_error(request, client_address)
self.shutdown_request(request)
def process_request(self, request, client_address):
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
t.daemon = self.daemon_threads
t.start()
在ThreadingMixIn类中,其实就定义了一个属性,两个方法。其中的process_request()方法实际调用的正是Python内置的多线程模块threading。这个模块是Python中所有多线程的基础,socketserver本质上也是利用了这个模块。
socketserver通过threading模块,实现了多线程任务处理能力,可以同时为多个客户提供服务。
那么,什么是线程,什么是进程?
进程是程序(软件,应用)的一个执行实例,每个运行中的程序,可以同时创建多个进程,但至少要有一个。每个进程都提供执行程序所需的所有资源,都有一个虚拟的地址空间、可执行的代码、操作系统的接口、安全的上下文(记录启动该进程的用户和权限等等)、唯一的进程ID、环境变量、优先级类、最小和最大的工作空间(内存空间)。进程可以包含线程,并且每个进程必须有至少一个线程。每个进程启动时都会最先产生一个线程,即主线程,然后主线程会再创建其他的子线程。
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不独立拥有系统资源,但它可与同属一个进程的其它线程共享该进程所拥有的全部资源。每一个应用程序都至少有一个进程和一个线程。在单个程序中同时运行多个线程完成不同的被划分成一块一块的工作,称为多线程。
举个例子,某公司要生产一种产品,于是在生产基地建设了很多厂房,每个厂房内又有多条流水生产线。所有厂房配合将整个产品生产出来,单个厂房内的流水线负责生产所属厂房的产品部件,每个厂房都拥有自己的材料库,厂房内的生产线共享这些材料。公司要实现生产必须拥有至少一个厂房一条生产线。换成计算机的概念,那么这家公司就是应用程序,厂房就是应用程序的进程,生产线就是某个进程的一个线程。
线程的特点:
线程是一个execution context(执行上下文),即一个cpu执行时所需要的一串指令。假设你正在读一本书,没有读完,你想休息一下,但是你想在回来时继续先前的进度。有一个方法就是记下页数、行数与字数这三个数值,这些数值就是execution context。如果你的室友在你休息的时候,使用相同的方法读这本书。你和她只需要这三个数字记下来就可以在交替的时间共同阅读这本书了。
线程的工作方式与此类似。CPU会给你一个在同一时间能够做多个运算的幻觉,实际上它在每个运算上只花了极少的时间,本质上CPU同一时刻只能干一件事,所谓的多线程和并发处理只是假象。CPU能这样做是因为它有每个任务的execution context,就像你能够和你朋友共享同一本书一样。
进程与线程区别:
同一个进程中的线程共享同一内存空间,但进程之间的内存空间是独立的。
同一个进程中的所有线程的数据是共享的,但进程之间的数据是独立的。
对主线程的修改可能会影响其他线程的行为,但是父进程的修改(除了删除以外)不会影响其他子进程。
线程是一个上下文的执行指令,而进程则是与运算相关的一簇资源。
同一个进程的线程之间可以直接通信,但是进程之间的交流需要借助中间代理来实现。
创建新的线程很容易,但是创建新的进程需要对父进程做一次复制。
一个线程可以操作同一进程的其他线程,但是进程只能操作其子进程。
线程启动速度快,进程启动速度慢(但是两者运行速度没有可比性)。
由于现代cpu已经进入多核时代,并且主频也相对以往大幅提升,多线程和多进程编程已经成为主流。Python全面支持多线程和多进程编程,同时还支持协程。
H. 如何理解python的多线程编程
线程是程序员必须掌握的知识,多线程对于代码的并发执行、提升代码效率和运行都至关重要。今天就分享一个黑马程序员Python多线程编程的教程,从0开始学习python多任务编程,想了解python高并发实现,从基础到实践,通过知识点 + 案例教学法帮助你想你想迅速掌握python多任务。
课程内容:
1.掌握多任务实现的并行和并发
2.掌握多进程实现多任务
3.掌握多线程实现多任务
4.掌握合理搭配多进程和线程
适用人群:
1、对python多任务编程感兴趣的在校生及应届毕业生。
2、对目前职业有进一步提升要求,希望从事python人工智能行业高薪工作的在职人员。
3、对python人工智能行业感兴趣的相关人员。
基础课程主讲内容包括:
1.python多任务编程
基础班课程大纲:
00-课程介绍
01-多任务介绍
02-进程介绍
03-使用多进程来完成多任务
04-多进程执行带有参数的任务
05-获取进程的编号
06-进程注意点
07-案例-多进程实现传智视频文件夹多任务拷贝器
08-线程介绍
09-使用多线程执行多任务
10-线程执行带有参数的任务
11-主线程和子线程的结束顺序
12-线程之间的执行顺序是无序
13-线程和进程的对比
14-案例-多线程实现传智视频文件夹多任务拷贝器
15-课程总结
I. 举一个例子,说明一个程序可能同时属于多个进程
不是程序属于进程这么说滴.楼主你概念搞错了了.
“
进程是在自身的虚拟地址空间正在运行的一个程序
程序运行产生进程
程序是一组静态的指令集,不占用系统运行资源
进程是随时都可能发生变化的,动态的.占用系统运行资源的程序
一个程序可以产生多个进程.
”
以上是我引用的一段话,简而言之就是,进程是程序的实例,一个程序可以有多个实例,但一个实例只能对应一个进程;呵呵,可能不太恰当,
J. Excel 如何实现excel打开多个文件是多进程
编程才行,不断的实例化excel进程,我还真测试过,效率奇低,用的时间是一个进程内打开的5到10倍