




已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Unix/Linux下一般想让某个程序在后台运行,很多都是使用&在程序结尾来让程序自动运行;但如果要想在退出终端后,程序依然还在后台运行,则要用nohup与&组合来实现。nohup 命令用途:不挂断地运行命令语法:nohup Command Arg . & 描述:nohup 命令运行由 Command参数和任何相关的Arg参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序:要运行后台中的 nohup 命令,需要添加&到命令的尾部。日志记录:无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的nohup.out 文件中。如果当前目录的nohup.out文件不可写,输出重定向到$HOME/nohup.out文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。使用时注意:在当shell中提示了nohup成功后,还需要按终端上键盘任意键退回到shell输入命令窗口,然后通过在shell中输入exit来退出终端;如果在nohup执行成功后直接点关闭程序按钮关闭终端的话,这时候会断掉该命令所对应的session,导致nohup对应的进程被通知需要一起shutdown,起不到关掉终端后调用程序继续后台运行的作用。例:$nohup DW_BATCH.sh &4 动态库移植方法如果要编制在两个系统中都能使用的动态链接库,通常会先选择在Windows的VC+提供的调试环境中完成初始的开发,毕竟VC+提供的图形化编辑和调试界面比vi和gcc方便许多。完成测试之后,再进行动态库的程序移植。通常gcc默认的编译规则比VC+默认的编译规则严格,即使在VC+下面没有任何警告错误的程序在gcc调试中也会出现许多警告错误,可以在gcc中采用-w选项关闭警告错误。下面给出程序移植需要遵循的规则以及经验。(1)尽量不要改变原有动态库头文件的顺序。通常在C/C+语言中,头文件的顺序有相当的关系。另外虽然C/C+语言区分大小写,但在包含头文件时,Linux必须与头文件的大小写相同,因为ext2文件系统对文件名是大小写敏感,否则不能正确编译,而在Windows下面,头文件大小写可以正确编译。(2)不同系统独有的头文件。在Windows系统中,通常会包括windows.h头文件,如果调用底层的通信函数,则会包含winsock.h头文件。因此在移植到Linux系统时,要注释掉这些Windows系统独有的头文件以及一些windows系统的常量定义说明,增加Linux都底层通信的支持的头文件等。(3)数据类型。VC+具有许多独有的数据类型,如_int16,_int32,TRUE,SOCKET等,gcc编译器不支持它们。通常做法是需要将windows.h和basetypes.h中对这些数据进行定义的语句复制到一个头文件中,再在Linux中包含这个头文件。例如将套接字的类型为SOCKET改为int。(4)关键字。VC+中具有许多标准C中所没有采用的关键字,如BOOL,BYTE,DWord,_asm等,通常在为了移植方便,尽量不使用它们,如果实在无法避免可以采用#ifdef 和#endif为LINUX和WINDOWS编写两个版本。(5)函数原型的修改。通常如果采用标准的C/C+语言编写的动态库,基本上不用再重新编写函数,但对于系统调用函数,由于两种系统的区别,需要改变函数的调用方式等,如在Linux编制的网络通信动态库中,用close()函数代替windows操作系统下的closesocket()函数来关闭套接字。另外在Linux下没有文件句柄,要打开文件可用open和fopen函数,(6)makefile的编写。在windows下面通常由VC+编译器来负责调试,但gcc需要自己动手编写makefile文件,也可以参照VC+生成的makefile文件。对于动态库移植,编译动态库时需要加入-shared选项。对于采用数学函数,如幂级数的程序,在调用动态库是,需要加入-lm。(7)其它一些需要注意的地方程序设计结构分析,对于移植他人编写的动态库程序,程序结构分析是必不可少的步骤,通常在动态库程序中,不会包含界面等操作,所以相对容易一些。在Linux中,对文件或目录的权限分为拥有者、群组、其它。所以在存取文件时,要注意对文件是读还是写操作,如果是对文件进行写操作,要注意修改文件或目录的权限,否则无法对文件进行写。指针的使用,定义一个指针只给它分配四个字节的内存,如果要对指针所指向的变量赋值,必须用malloc函数为它分配内存或不把它定义为指针而定义为变量即可,这点在linux下面比windows编译严格。同样结构不能在函数中传值,如果要在函数中进行结构传值,必须把函数中的结构定义为结构指针。路径标识符,在Linux下是“/”,在Windows下是“”,注意windows和Linux的对动态库搜索路径的不同。linux下的共享对象(动态链接库)(源于网络,归于网络)2012-09-07 10:16:34|分类:linux|举报|字号订阅nm libswapi.a | grep swNewtran查询库里面是否有这个函数1 简介大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程序需要按需装入,同时其执行代码可在多个执行程序间共享,节省了空间,提高了效率,具备很高的灵活性,得到越来越多程序员和用户的青睐。那么,在LINUX系统中有无这样的函数库呢? 答案是肯定的,LINUX的动态链接库不仅有,而且为数不少。在/lib目录下,就有许多以.so作后缀的文件,这就是LINUX系统应用的动态链接库,只不过与WINDOWS叫法不同,它叫so,即Shared Object,共享对象。-2 如何创建动态链接库生成动态链接库:如:1.gcc -fpic -shared -o example.so example1.c example2.c-fpic 使输出的对象模块是按照可重定位地址方式生成的。-shared指定把对应的源文件生成对应的动态链接库文件libstr.so文件。3 如何使用动态链接库3.1 dlfcn.h头文件Linux下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接库的函数的原型。下面详细说明一下这些函数。3.1.1 dlerror原型:1.const char *dlerror(void);作用:当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。3.1.2 dlopen原型:1.void *dlopen (const char *filename, int flag);作用:dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。参数说明:filename: so文件名.如果名字不以/开头,则非绝对路径名,将按下列先后顺序查找该文件。(1) 用户环境变量中的LD_LIBRARY值;(2) 动态链接缓冲文件/etc/ld.so.cache(3) 目录/lib,/usr/lib.flag:表示在什么时候解决未定义的符号(调用)。取值有两个:1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。2) RTLD_NOW : 表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。dlopen调用失败时,将返回NULL值,否则返回的是操作句柄。3.1.3 dlsym原型:1.void *dlsym(void *handle, char *symbol);作用:dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。由此地址,可以带参数执行相应的函数。举例:1.void handle =NULL;2.void (*add)(int x,int y); 3.4.handle =dlopen(xxx.so,RTLD_LAZY); 5.if (!handler) 6. printf( 加载模块错误 %sn, dlerror() ); 7. return; 8.9.add=dlsym(handle,add); 10.if(add) 11. add(89,369);12.dlclose(handle);3.1.4 dlclose原型:1.int dlclose (void *handle);作用:dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。充分利用共享内存并不总是容易的。在本文中,IBM 的 Sachin Agrawal 与我们共享了他的 C+ 专门技术,展示了面向对象如何去利用一个独特而实用的进程间通信通道的关键优势。就时间和空间而言,共享内存可能是所有现代操作系统都具备的最高效的进程间通信通道。共享内存 同时将地址空间映射到多个进程:一个进程只需依附到共享内存并像使用普通内存一样使用它,就可以开始与其他进程进行通信。不过,在面向对象编程领域中,进程更倾向于使用共享对象而不是原始的信息。通过对象,不需要再对对象中容纳的信息进行序列化、传输和反序列化。共享对象也驻留在共享内存中,尽管这种对象“属于”创建它们的进程,但是系统中的所有进程都可以访问它们。因此,共享对象中的所有信息都应该是严格与特定进程无关的。这与当前所有流行的编译器所采用的 C+ 模型是直接矛盾的:C+ 对象中总是包含指向各种 Vee-Table 和子对象的指针,这些是 与特定进程相关的。要让这种对象可以共享,您需要确保在所有进程中这些指针的目标都驻留在相同的地址。在一个小的示例的帮助下,本文展示了在哪些情况下 C+ 模型可以成功使用共享内存模型,哪些情况下不能,以及可能从哪里着手。讨论和示例程序都只限于非静态数据成员和虚函数。其他情形不像它们这样与 C+ 对象模型关系密切:静态的和非静态非虚拟的成员函数在共享环境中没有任何问题。每个进程的静态成员不驻留在共享内存中(因此没有问题),而共享的静态成员的问题与这里讨论到的问题类似。环境假定本文仅局限于用于 32 位 x86 Interl 体系结构的 Red Hat Linux 7.1,使用版本 2.95 的 GNU C+ 编译器及相关工具来编译和测试程序。不过,您同样可以将所有的思想应用到任意的机器体系结构、操作系统和编译器组合。示例程序示例程序由两个客户机构成:shm_client1 和 shm_client2,使用由共享对象库 shm_server 提供的共享对象服务。对象定义在 common.h 中:清单 1. common.h 中的定义#ifndef _COMMON_H_ #define _COMMON_H_class A public: int m_nA; virtual void WhoAmI();static void * m_sArena; void * operator new (unsigned int); ;class B : public A public: int m_nB; virtual void WhoAmI(); ;class C : virtual public A public: int m_nC; virtual void WhoAmI(); ;void GetObjects(A * pA, B * pB, C * pC);#endif /_COMMON_H_清单 1 定义了三个类(A、B 和 C),它们有一个共同的虚函数 WhoAmI()。基类 A 有一个名为 m_nA 的成员。定义静态成员 m_sArena 和重载操作 new() 是为了可以在共享内存中构造对象。类 B 简单地从 A 继承,类 C 从 A 虚拟地继承。为了确保 A、B 和 C 的大小明显不同,定义了 B:m_nB 和 C:m_nC。这样就简化了 A:operator new() 的实现。GetObjects() 接口返回共享对象的指针。共享库的实现在 shm_server.cpp 中: 清单 2. 库 - shm_server.cpp#include #include #include #include #include #include #include common.hvoid * A:m_sArena = NULL;void * A:operator new (unsigned int size) switch (size) case sizeof(A): return m_sArena;case sizeof(B): return (void *)(int)m_sArena + 1024);case sizeof(C): return (void *)(int)m_sArena + 2048);default: cerr _FILE_ : _LINE_ Critical error endl; void A:WhoAmI() cout Object type: A endl; void B:WhoAmI() cout Object type: B endl; void C:WhoAmI() cout Object type: C endl; void GetObjects(A * pA, B * pB, C * pC) *pA = (A *)A:m_sArena; *pB = (B *)(int)A:m_sArena + 1024); *pC = (C *)(int)A:m_sArena + 2048); class Initializer public: int m_shmid; Initializer();static Initializer m_sInitializer; ;Initializer Initializer:m_sInitializer;Initializer:Initializer() key_t key = 1234; bool bCreated = false;m_shmid = shmget(key, 3*1024, 0666);if (-1 = m_shmid) if (ENOENT != errno) cerr _FILE_ : _LINE_ Critical error endl; return; m_shmid = shmget(key, 3*1024, IPC_CREAT | 0666);if (-1 = m_shmid) cerr _FILE_ : _LINE_ Critical error endl; return; cout Created the shared memory endl; bCreated = true; A:m_sArena = shmat(m_shmid, NULL, 0);if (-1 = (int)A:m_sArena) cerr _FILE_ : _LINE_ Critical error m_nA = 1; pA = new B; pA-m_nA = 2; pA = new C; pA-m_nA = 3; return; 让我们更详细地研究清单 2: 第 9-25 行:operator new ()同一个重载的操作符让您可以在共享内存中构造类 A、B 和 C 的对象。对象 A 直接从共享内存的起始处开始。对象 B 从偏移量 1024 处开始,C 从偏移量 2048 处开始。第 26-34 行:虚函数 虚函数简单地向标准输出写一行文本。第 35-39 行:GetObjects GetObjects() 返回指向共享对象的指针。第 40-46 行:初始化器(Initializer) 这个类存储共享内存标识符。它的构造函数创建共享内存及其中的对象。如果共享内存已经存在,它就只是依附到现有的共享内存。静态成员 m_sInitializer 确保在使用共享库的客户机模块的 main() 函数之前调用构造函数。第 48-82 行:Initializer:Initializer() 如果原来没有共享内存,则创建,并在其中创建共享对象。如果共享内存已经存在,对象的构造就会被跳过。Initializer:m_shmid 记录标识符,A:m_sArena 记录共享内存地址。即使所有进程都不再使用它了,共享内存也不会被销毁。这样就让您可以显式地使用 ipcs 命令来销毁它,或者使用 ipcs 命令进行一些速查。客户机进程的实现在 shm_client.cpp 中: 清单 3. 客户机 - shm_client.cpp#include common.h#include #include int main (int argc, char * argv) int jumpTo = 0;if (1 jumpTo) | (6 jumpTo) jumpTo = 1; A * pA; B * pB; C * pC;GetObjects(&pA, &pB, &pC);cout (int)pA t; cout (int)pB t; cout (int)pC n;switch (jumpTo) case 1: cout m_nA WhoAmI();case 3: cout m_nA WhoAmI();case 5: cout m_nA WhoAmI(); return 0; #include void DoNothingCode() pthread_create(NULL, NULL, NULL, NULL); 第 6-35 行 客户机进程获得指向三个共享对象的指针,建立对它们的数据成员的三个引用,并且 依赖于命令行的输入 调用三个虚函数。第 36-39 行 没有被调用的 pthread_create() 函数用来强制链接到另一个共享库。来自所有共享库的任何方法都可以满足这一目的。共享库和客户机可执行文件的两个实例的编译方法如下:gcc shared g shm_server.cpp o libshm_server.so lstdc+ gcc -g shm_client.cpp -o shm_client1 -lpthread -lshm_server -L . gcc -g shm_client.cpp -o shm_client2 -lshm_server -L . lpthread注意,交换了 shm_client1 和 shm_client2 中 shm_server 和 pthread 的链接顺序,以确保 shm_server 共享库在两个可执行文件中的基址不同。可以使用 ldd 命令进一步验证这一点。示例输出通常如下所示: 清单 4. shm_client1 的库映射ldd shm_client1libpthread.so.0 = (0x4002d000) libshm_server.so = (0x40042000) libc.so.6 = (0x4005b000) ld-linux.so.2 = (0x40000000) 清单 5. shm_client2 的库映射 ldd shm_client2libshm_server.so = (0x40018000) libpthread.so.0 = (0x40046000) libc.so.6 = (0x4005b000) ld-linux.so.2 = (0x40000000)这里的主要目的是使构建的两个客户机二进制文件具有不同的服务器库基址。在这个示例程序的上下文中,使用不被调用的 pthread_create() 函数和不同的共享库链接顺序来达到这一目标。不过,没有具体规则或统一步骤可以作用于所有链接;需要根据不同的情况采取不同的方法。例 1:shm_client1 与 shm_client1 在下面的输出中,首先在 shell 中调用 shm_client1。由于现在没有共享对象,于是 shm_client1 创建了它们,引用它们的数据成员,调用它们的虚函数,然后退出 将对象留在了内存中。第二次,进程只是引用数据成员和虚函数。清单 6. shm_client1 与 shm_client1 的输出日志$ ./shm_client1Created the shared memory 1073844224 1073845248 1073846272 1 Object type: A 2 Object type: B 3 Object type: C$ ipcs- Shared Memory Segments -key shmid owner perms bytes nattch status 0x000004d2 2260997 sachin 666 3072 0$ ./shm_client1 1073840128 1073841152 1073842176 1 Object type: A 2 Object type: B - 0 - Segmentation fault (core dumped)当第二个进程试图通过类型 C * 的指针去引用数据成员 A:m_nA 时(您会记得 C 虚拟继承自 A),共享对象内的基子对象(base sub-object)指针会被读取。共享对象是在现在不存在的进程的上下文中构造的。因此,读取 A:m_nA 和 C:WhoAmI() 时读入的是内存垃圾。因为 Vee-Table 和虚函数位于 shm_server 共享库内部,恰巧在同一虚拟地址被重新加载,所以,再次引用类型 A * 和 B * 的指针时不会观察到任何问题。因此,GNU 所采用的 C+ 对象模型没有成功地处理虚拟继承。例 2:shm_client1 与 shm_client2 在下一个示例输出中,在命令行中首先执行 shm_client1,然后执行 shm_client2: 清单 7. shm_client1 与 sh
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【正版授权】 ISO/TR 25087:2025 EN Space systems - Study of electrical wire derating
- 【正版授权】 ISO 22002-4:2025 EN Prerequisite programmes on food safety - Part 4: Food packaging manufacturing
- GB/T 20222-2025防复印技术产品通用技术条件
- 【正版授权】 IEC 61293:1994 EN-D Marking of electrical equipment with ratings related to electrical supply - Safety requirements
- 校园性防侵害安全知识培训课件
- 校园安全知识培训课件讲话稿
- 校园安全知识培训课件简讯
- 函数高三试题及答案
- 法语时态试题及答案
- 校园保安消防知识培训课件
- 神经内科常规用药指南
- 矿业公司采矿管理制度
- 新疆维吾尔自治区国际创伤生命支持ITLS职业考试试卷与答案
- 非标设备公司采购管理制度
- 2025年的基层治理理论与实践考核试卷及答案
- 2025年江西省高考物理真题
- 甘肃白银有色集团股份有限公司招聘考试真题2024
- 外贸合伙人合同协议书
- 登销记以及运统46系统运用21课件
- 《电磁感应现象解析》课件
- 职业技术学院旅游管理专业《智慧旅游技术应用》课程标准
评论
0/150
提交评论