- 浏览: 665276 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
sztime:
可以在文本框上绑定事件来禁用回车键, 我就是这样做的.在IE中 ...
form 回车自动提交问题 -
damoqiongqiu:
非常好的文章,很透彻不过有一句话小僧腆着脸补充一下:“1111 ...
为什么要用补码来做存储 -
wuyizhong:
原来如此啊。
form 回车自动提交问题 -
luliangy:
谢楼主~!
用C语言扩展Python的功能 -
kwong:
很有用,谢谢
火狐和IE 对css 样式解释的差异
关于“RPC语言”
RPC语言也是一种专门的编程语言,当然这里我们不需要知道太多,只需要能看懂下面这种基本结构就行了:
program TESTPROG { version VERSION { string TEST(string) = 1; } = 1; } = 87654321; |
这里TESTPROG和VERSION是两个变量,用于标识一个单独的RPC接口。这被RPC服务程序,比如portmap用到,我们可以不用关心,变量名字也是随便取的。但取值要在你的系统中是唯一的。
“string
TEST(string) =
1;”这一行说明有两个函数test_VERSION和test_VERSION_svc,这里由于VERSION变量为1,所以函数名为test_1和
test_1_svc,这两个函数用于在服务器端和客户端实现调用,即:
在客户端调用test_1函数,服务器端调用test_1_svc函数处理并返回。
函数的类型是string,RPC语言中string即C里面的一个字符串。所以上述函数有一个字符串作为参数传递,同时要返回字符串。即:
char ** test_1(char **argp, CLIENT *clnt) 和 char **test_1_svc(char **argp, struct svc_req *rqstp)
同理,如果声明是这样的:
program RDICTPROG /* name of remote program ( not used ) */ { version RDICTVERS /* declaration of version ( see below ) */ { int INITW ( void ) = 1; /* first procedure in this program */ int INSERTW ( string ) = 2; /* second procedure in this program */ int DELETEW ( string ) = 3; /* third procedure in this program */ int LOOKUPW ( string ) = 4; /* fourth procedure in this program */ } = 1; /* definition of the program version */ } = 0x30090949; /* remote program number ( must be unique ) */ |
则
说明这个RPC中有四个函数可用,即客户端可以调用initw_1、insertw_1、deletew_1、lookupw_1四个函数来向服务端发送
消息,服务端可以用initw_1_svc、insertw_1_svc、deletew_1_svc、lookupw_1_svc四个函数来处理请求并
返回结果。
原任务
假设现在有这样一个程序,源代码如下:
/* dict.c -- main, initw, nextin, insertw, deletew, lookupw */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define MAXWORD 50 /* maximum length of a command or word */ #define DICTSIZ 100 /* maximum number of entries in dictionary. */ char dict[DICTSIZ][MAXWORD + 1]; /* storage for a dictionary of words */ int nwords = 0; /* number of words in the dictionary */ /* 函数原型 */ int nextin(char *cmd, char *word); int initw(void); int insertw(const char *word); int deletew(const char *word); int lookupw(const char *word); /* ------------------------------------------------------------------ * main -- insert, delete, or lookup words in a dictionary as specified * ------------------------------------------------------------------ */ int main(int argc, char *argv[]) { char word[MAXWORD + 1]; /* space to hold word from input line */ char cmd; int wordlen; /* length of input word */ printf("Please input:\n"); while (1) { wordlen = nextin(&cmd, word); if (wordlen < 0) { exit(0); } switch (cmd) { case 'I': /* 初始化 */ initw(); printf("Dictionary initialized to empty.\n"); break; case 'i': /* 插入 */ insertw(word); printf("%s inserted.\n", word); break; case 'd': /* 删除 */ if (deletew(word)) { printf("%s deleted.\n", word); } else { printf("%s not found.\n", word); } break; case 'l': /* 查询 */ if (lookupw(word)) { printf("%s was found.\n", word); } else { printf("%s was not found.\n", word); } break; case 'q': /* 退出 */ printf("Program quits.\n"); exit(0); break; default: /* 非法输入 */ printf("command %c invalid.\n", cmd); break; } /* end of switch */ } /* end of while */ return 0; } /* end of main */ /* ------------------------------------------------------------------ * nextin -- read a command and(possibly) a word from the next input line * ------------------------------------------------------------------ */ int nextin(char *cmd, char *word) { int i, ch; ch = getc(stdin); while (isspace(ch)) { ch = getc(stdin); } /* end of while */ if (ch == EOF) { return (-1); } *cmd = (char) ch; ch = getc(stdin); while (isspace(ch)) { ch = getc(stdin); } /* end of while */ if (ch == EOF) { return (-1); } if (ch == '\n') { return (0); } i = 0; while (!isspace(ch)) { if (++i > MAXWORD) { printf("error: word too long.\n"); exit(1); } *word++ = ch; ch = getc(stdin); } /* end of while */ *word = '\0'; /* 原来的代码这里有问题 */ return i; } /* end of nextin */ /* ------------------------------------------------------------------ * initw -- initialize the dictionary to contain no words at all * ------------------------------------------------------------------ */ int initw(void) { nwords = 0; return 1; } /* end of initw */ /* ------------------------------------------------------------------ * insertw -- insert a word in the dictionary * ------------------------------------------------------------------ */ int insertw(const char *word) { strcpy(dict[nwords], word); nwords++; return (nwords); } /* end of insertw */ /* ------------------------------------------------------------------ * deletew -- delete a word from the dictionary * ------------------------------------------------------------------ */ int deletew(const char *word) { int i; for (i = 0; i < nwords; i++) { if (strcmp(word, dict[i]) == 0) { nwords--; strcpy(dict[i], dict[nwords]); return (1); } } /* end of for */ return (0); } /* end of deletew */ /* ------------------------------------------------------------------ * lookupw -- look up a word in the dictionary * ------------------------------------------------------------------ */ int lookupw(const char *word) { int i; for (i = 0; i < nwords; i++) { if (strcmp(word, dict[i]) == 0) { return (1); } } /* end of for */ return (0); } /* end of lookupw */ |
这是一个简单的字典程序,即程序运行起来以后维护着一个字典库,用户可以向里面添加词语,也可以查询或删除词语。
当然,这个程序只能在同一台主机上运行。程序整个运行过程中,只需要完成如下几个步骤:
A、接受用户输入;
B、分析用户输入决定是否进行下面的步骤:
1、初始化数据库;
2、向数据库添加词语;
3、查询或删除词语
任务分解
大家可以想到,对于一个大型系统,比如需要有很多人维护这个系统的数据。象上面这样独立的程序就不适用了,需要做成分布式系统:
即一个服务器维护着数据库,任何客户端都可以接受用户请求,客户端分析用户命令后提交给服务器去处理。
所以我们可能会把程序分成两部分:
客户端:接受用户输入,并判断用户输入内容的正确性,向服务器提交数据,等服务器返回消息
服务器端:维护数据,接受客户端命令并执行后返回结果。
所以我们把上面这个程序分解成下面两部分:
/* dict1.c -- main, nextin */ #include <stdio.h> #include <stdlib.h> #define MAXWORD 50 /* maximum length of a command or word */ /* ------------------------------------------------------------------ * main -- insert, delete, or lookup words in a dictionary as specified * ------------------------------------------------------------------ */ int main(int argc, char *argv[]) { char word[MAXWORD + 1]; /* space to hold word from input line */ char cmd; int wordlen; /* length of input word */ printf("Please input:\n"); while (1) { wordlen = nextin(&cmd, word); if (wordlen < 0) { exit(0); } switch (cmd) { case 'I': /* 初始化 */ initw(); printf("Dictionary initialized to empty.\n"); break; case 'i': /* 插入 */ insertw(word); printf("%s inserted.\n", word); break; case 'd': /* 删除 */ if (deletew(word)) { printf("%s deleted.\n", word); } else { printf("%s not found.\n", word); } break; case 'l': /* 查询 */ if (lookupw(word)) { printf("%s was found.\n", word); } else { printf("%s was not found.\n", word); } break; case 'q': /* 退出 */ printf("Program quits.\n"); exit(0); break; default: /* 非法输入 */ printf("command %c invalid.\n", cmd); break; } /* end of switch */ } /* end of while */ return 0; } /* end of main */ /* ------------------------------------------------------------------ * nextin -- read a command and(possibly) a word from the next input line * ------------------------------------------------------------------ */ int nextin(char *cmd, char *word) { int i, ch; ch = getc(stdin); while (isspace(ch)) { ch = getc(stdin); } /* end of while */ if (ch == EOF) { return (-1); } *cmd = (char) ch; ch = getc(stdin); while (isspace(ch)) { ch = getc(stdin); } /* end of while */ if (ch == EOF) { return (-1); } if (ch == '\n') { return (0); } i = 0; while (!isspace(ch)) { if (++i > MAXWORD) { printf("error: word too long.\n"); exit(1); } *word++ = ch; ch = getc(stdin); } /* end of while */ *word = '\0'; return i; } /* end of nextin */ |
和
/* dict2.c -- initw, insertw, deletew, lookupw */ #include <string.h> #define MAXWORD 50 /* maximum length of a command or word */ #define DICTSIZ 100 /* maximum number of entries in dictionary. */ char dict[DICTSIZ][MAXWORD + 1]; /* storage for a dictionary of words */ int nwords = 0; /* number of words in the dictionary */ /* ------------------------------------------------------------------ * initw -- initialize the dictionary to contain no words at all * ------------------------------------------------------------------ */ int initw(void) { nwords = 0; return 1; } /* end of initw */ /* ------------------------------------------------------------------ * insertw -- insert a word in the dictionary * ------------------------------------------------------------------ */ int insertw(const char *word) { strcpy(dict[nwords], word); nwords++; return (nwords); } /* end of insertw */ /* ------------------------------------------------------------------ * deletew -- delete a word from the dictionary * ------------------------------------------------------------------ */ int deletew(const char *word) { int i; for (i = 0; i < nwords; i++) { if (strcmp(word, dict[i]) == 0) { nwords--; strcpy(dict[i], dict[nwords]); return (1); } } /* end of for */ return (0); } /* end of deletew */ /* ------------------------------------------------------------------ * lookupw -- look up a word in the dictionary * ------------------------------------------------------------------ */ int lookupw(const char *word) { int i; for (i = 0; i < nwords; i++) { if (strcmp(word, dict[i]) == 0) { return (1); } } /* end of for */ return (0); } /* end of lookupw */ |
这两部分代码只是在功能上实现了分离,显然实现通讯的部分还没有,下面我们利用RPC来快速实现通讯。
利用RPC实现分布式系统
首先,建立一个RPC源文件,源代码rdict.x如下:
/* rdict.x */ /* RPC declarations for dictionary program */ const MAXWORD = 10; /* maximum length of a command or word */ const DICTSIZ = 3; /* number of entries in dictionary */ struct example /* unused structure declared here to */ { int exfield1; /* illustrate how rpcgen builds XDR */ char exfield2; /* routines to convert structures */ }; /* ------------------------------------------------------------------ * RDICTPROG -- remote program that provides insert, delete, and lookup * ------------------------------------------------------------------ */ program RDICTPROG /* name of remote program ( not used ) */ { version RDICTVERS /* declaration of version ( see below ) */ { int INITW ( void ) = 1; /* first procedure in this program */ int INSERTW ( string ) = 2; /* second procedure in this program */ int DELETEW ( string ) = 3; /* third procedure in this program */ int LOOKUPW ( string ) = 4; /* fourth procedure in this program */ } = 1; /* definition of the program version */ } = 0x30090949; /* remote program number ( must be unique ) */ |
然后用下列命令产生服务器端函数rdict_srv_func.c:
rpcgen -Ss -o rdict_srv_func.c rdict.x |
然后用下列命令产生客户端程序rdict_client.c:
rpcgen -Sc -o rdict_client.c rdict.x |
/************关于本文档********************************************
*filename: 我是这样学习Linux下C语言编程的-利用RPC快速实现分布式系统
*purpose: 说明如何利用RPC快速进行客户端-服务器端C-S结构编程
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-02-27 19:20
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to:
* Ubuntu 本程序在Ubuntu 6.10系统上测试完全正常
* Google.com 我通过google搜索并参考了RPC编程相关的许多文章
* 网络安全焦点(www.xfocus.net) 我主要借鉴了此文 http://www.xfocus.net/articles/200009/10.html
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
然后用下列命令产生Makefile:
rpcgen -Sm rdict.x > Makefile |
Makefile文件原内容如下:
# This is a template Makefile generated by rpcgen # Parameters CLIENT = rdict_client SERVER = rdict_server SOURCES_CLNT.c = SOURCES_CLNT.h = SOURCES_SVC.c = SOURCES_SVC.h = SOURCES.x = rdict.x TARGETS_SVC.c = rdict_svc.c rdict_xdr.c TARGETS_CLNT.c = rdict_clnt.c rdict_xdr.c TARGETS = rdict.h rdict_xdr.c rdict_clnt.c rdict_svc.c OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o) # Compiler flags CFLAGS += -g LDLIBS += -lnsl RPCGENFLAGS = # Targets all : $(CLIENT) $(SERVER) $(TARGETS) : $(SOURCES.x) rpcgen $(RPCGENFLAGS) $(SOURCES.x) $(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c) $(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c) $(CLIENT) : $(OBJECTS_CLNT) $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS) $(SERVER) : $(OBJECTS_SVC) $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS) clean: $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER) |
动手修改Makefile,修改后内容如下:
# This is a template Makefile generated by rpcgen # Parameters CLIENT = rdict_client SERVER = rdict_server SOURCES_CLNT.c = SOURCES_CLNT.h = SOURCES_SVC.c = SOURCES_SVC.h = SOURCES.x = rdict.x TARGETS_SVC.c = rdict_svc.c rdict_xdr.c rdict_srv_func.c TARGETS_CLNT.c = rdict_clnt.c rdict_xdr.c rdict_client.c TARGETS = rdict.h rdict_xdr.c rdict_clnt.c rdict_svc.c OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o) # Compiler flags CFLAGS += -g LDLIBS += -lnsl RPCGENFLAGS = # Targets all : $(CLIENT) $(SERVER) $(TARGETS) : $(SOURCES.x) rpcgen $(RPCGENFLAGS) $(SOURCES.x) $(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c) $(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c) $(CLIENT) : $(OBJECTS_CLNT) $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS) $(SERVER) : $(OBJECTS_SVC) $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS) clean: $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER) *~ |
修改客户端源代码rdict_client.c,把接受用户输入并分析用户输入内容的部分加到程序中来。修改后的代码为:
/* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "rdict.h" /* ------------------------------------------------------------------ * nextin -- read a command and(possibly) a word from the next input line * ------------------------------------------------------------------ */ int nextin(char *cmd, char *word) { int i, ch; ch = getc(stdin); while (isspace(ch)) { ch = getc(stdin); } /* end of while */ if (ch == EOF) { return (-1); } *cmd = (char) ch; ch = getc(stdin); while (isspace(ch)) { ch = getc(stdin); } /* end of while */ if (ch == EOF) { return (-1); } if (ch == '\n') { return (0); } i = 0; while (!isspace(ch)) { if (++i > MAXWORD) { printf("error: word too long.\n"); exit(1); } *word++ = ch; ch = getc(stdin); } /* end of while */ *word = '\0'; return i; } /* end of nextin */ void rdictprog_1(char *host) { CLIENT *clnt; int *result_1; char *initw_1_arg; int *result_2; char *insertw_1_arg; int *result_3; char *deletew_1_arg; int *result_4; char *lookupw_1_arg; #ifndef DEBUG clnt = clnt_create(host, RDICTPROG, RDICTVERS, "udp"); if (clnt == NULL) { clnt_pcreateerror(host); exit(1); } #endif /* DEBUG */ char word[MAXWORD + 1]; /* space to hold word from input line */ char cmd; int wordlen; /* length of input word */ while (1) { printf("\nPlease input:"); wordlen = nextin(&cmd, word); if (wordlen < 0) { exit(0); } /* printf("\nYour cmd is:%c, your word is:%s\n", cmd, word); */ switch (cmd) { case 'I': /* 初始化 */ result_1 = initw_1((void *) &initw_1_arg, clnt); /* printf("\nYour result is:%d\n", *result_1); */ if (result_1 == (int *) NULL) clnt_perror(clnt, "call failed"); else if(*result_1 ==0) printf("Dictionary initialized to empty.\n"); else printf("Dictionary have already initialized.\n"); break; case 'i': /* 插入 */ insertw_1_arg = word; result_2 = insertw_1(&insertw_1_arg, clnt); /* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_2, insertw_1_arg, strlen(insertw_1_arg)); */ if (result_2 == (int *) NULL) clnt_perror(clnt, "call failed"); else printf("%s inserted.\n", word); break; case 'd': /* 删除 */ deletew_1_arg = word; result_3 = deletew_1(&deletew_1_arg, clnt); /* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_3, deletew_1_arg, strlen(deletew_1_arg)); */ if (result_3 == (int *) NULL) clnt_perror(clnt, "call failed"); else printf("%s deleted.\n", word); break; case 'l': /* 查询 */ lookupw_1_arg = word; result_4 = lookupw_1(&lookupw_1_arg, clnt); /* printf("\nYour result is:%d, your string is:%s(%d)\n", *result_4, lookupw_1_arg, strlen(lookupw_1_arg)); */ if (result_4 == (int *) NULL) clnt_perror(clnt, "call failed"); else if(*result_4 ==0) printf("%s found.\n", word); else printf("%s not found.\n", word); break; case 'q': /* 退出 */ printf("Program quits.\n"); exit(0); break; default: /* 非法输入 */ printf("Command %c(%s) invalid.\n", cmd, word); break; } /* end of switch */ } /* end of while */ #ifndef DEBUG clnt_destroy(clnt); #endif /* DEBUG */ } int main(int argc, char *argv[]) { char *host; if (argc < 2) { printf("usage: %s server_host\n", argv[0]); exit(1); } host = argv[1]; rdictprog_1(host); exit(0); } |
同时修改服务器端代码rdict_srv_func.c,修改后内容为:
/* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "rdict.h" char dict[DICTSIZ][MAXWORD + 1]; /* storage for a dictionary of words */ int nwords = 0; /* number of words in the dictionary */ char init_bool = 0; int initw(void) { if(init_bool) return 1; nwords = 0; init_bool = 1; return 0; } /* end of initw */ /* ------------------------------------------------------------------ * insertw -- insert a word in the dictionary * ------------------------------------------------------------------ */ int insertw(const char *word) { strcpy(dict[nwords%DICTSIZ], word); nwords++; return (nwords); } /* end of insertw */ /* ------------------------------------------------------------------ * deletew -- delete a word from the dictionary * ------------------------------------------------------------------ */ int deletew(const char *word) { int i; for (i = 0; i < nwords; i++) { if (strcmp(word, dict[i]) == 0) { nwords--; strcpy(dict[i], dict[nwords]); return (1); } } /* end of for */ return (0); } /* end of deletew */ /* ------------------------------------------------------------------ * lookupw -- look up a word in the dictionary * ------------------------------------------------------------------ */ int lookupw(const char *word) { int i; for (i = 0; i < nwords; i++) { if (strcmp(word, dict[i]) == 0) { return 0; } } /* end of for */ return 1; } /* end of lookupw */ int *initw_1_svc(void *argp, struct svc_req *rqstp) { static int result; /* * insert server code here */ result = initw(); return &result; } int *insertw_1_svc(char **argp, struct svc_req *rqstp) { static int result; /* * insert server code here */ result = insertw(*argp); return &result; } int *deletew_1_svc(char **argp, struct svc_req *rqstp) { static int result; /* * insert server code here */ result = deletew(*argp); return &result; } int *lookupw_1_svc(char **argp, struct svc_req *rqstp) { static int result; /* * insert server code here */ result = lookupw(*argp); return &result; } |
至此,程序做好了。输入一个make命令就可以生成test_server和test_client这两个可执行程序了。
在一台机器上运行./test_server程序,在另外的客户机上运行./test_client server_ip就可以了。这里server_ip是运行着test_server程序的主机的IP地址。
发表评论
-
信号表
2010-09-02 00:59 560SIGHUP 终止进程 终端线路挂断 SI ... -
Mogile安装实践
2008-09-01 22:05 2127Mogile安装实践 Filed under: Mog ... -
ld.so.conf 文档和PKG_CONFIG_PATH变量
2008-08-30 02:37 2305一、编译和连接 ... -
gcc 安装
2008-08-25 02:26 3503关于GCC的升级,一定要用rpm包吗? 參考:::2004年 ... -
g++下 hash_map
2008-08-25 01:33 3378一个hash_map使用错误 g++ ... -
stdport 安装
2008-08-25 01:27 969stlport安装使用手记 段� ... -
Linux下编写动态链接库的简单过程
2008-07-10 01:12 3082(1) 使用编译选项 -fPIC ,产生与位置无关 ... -
Linux内核中的进程组及会话
2008-04-26 15:22 6102将阐述Linux内核中的如下几个概念 1) 进程组 2) 会话 ... -
rsync中文手册
2007-08-31 00:55 927用rsync实现网站镜像和 ... -
管理幽默:三个囚犯的选择
2007-10-13 20:13 716有一个美国人、一个法国人和一个犹太人要被关进监狱3年。监狱长让 ... -
linux下批量替换一个目录下的文件某个字符串
2007-12-28 01:19 1079太酷了!! sed -i "s/oldstring/ ... -
linux下编程学习--- 静态库和动态库的编译
2008-02-03 16:28 2233学习linux下c很长一段对动态库和静态库的编译和使用总是 ... -
linux下编程学习----- 线程同步之无名信号量
2008-02-04 14:49 2161这是一个书上的例子,逻辑是:一个线程生产一组数字1、2、3. ... -
linux下编程学习----- 远程过程调用(rpc)
2008-02-19 18:14 6581一、概述 在传统的编程概念中,过程是由程序员在本地 ... -
linux学习之-- 性能分析
2008-02-22 18:57 1211http://hi.baidu.com/chegaoying/ ... -
linux性能分析 -- top
2008-02-22 19:36 10032top top命令是最流行的性能工具之一。大多数系统管理员运行 ... -
linux性能分析 -- sar
2008-02-22 19:37 14423sarsar是一个优秀的一般性能监视工具,它可以输出Linux ... -
linux性能分析 -- vmstat
2008-02-22 19:38 3517vmstatvmstat命令也是显示Linux性能指标的方法, ... -
linux性能分析 -- iostat
2008-02-22 19:39 3743iostatiostat命令是另一个� ... -
linux性能分析 -- free
2008-02-22 19:40 869free free命令输出内存和交换信息,与top命令的作用非 ...
相关推荐
Linux(Ubuntu)COM串口应用例程源码: /*打开串口函数*/ int open_port(int com_port) { int fd; #if (COM_TYPE == GNR_COM) char *dev[] = {"/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2"}; #else char *dev[] = {...
这个“linux下消息队列例程源码.zip”压缩包很可能包含了一些示例代码,用于演示如何在Linux内核环境下使用消息队列。下面将详细介绍Linux消息队列的基本概念、API及其在驱动开发中的应用。 **1. 消息队列的概念** ...
RPC(Remote Procedure Call)是一种计算机通信协议,它允许程序在一台计算机上执行远程操作,就像调用本地函数一样。在Linux环境下,实现RPC通常涉及...希望这个详尽的指南能帮助你理解和实现RPC在Linux环境下的应用。
STM32官方USB OTG例程详解主要集中在STM32微控制器如何利用USB OTG功能实现设备间的通信,特别是以JoyStickMouse为例进行说明。USB OTG(On-The-Go)是一种扩展USB规范,允许设备在没有主机的情况下互相通信。 在...
Modbus RTU 主站指令库应用例程
verilog_PLI参考手册_tf和acc例程详解
标题中“linux下socket can 编程详解”所指的知识点涉及到Linux操作系统环境下对Socket CAN的编程方法。Socket CAN是Linux内核中实现CAN总线网络协议的标准接口。它允许用户空间的程序通过标准套接字接口与CAN总线...
先在命令行运行make编译,生成串口读写共享库,然后运行gcc -s -shared -fPIC test.c -lSetupSerialPort -o test.so,...还有Linux下Socket通讯开发例程及Firefox浏览器插件开发例程,有空时会一起整理出来贡献给大家
本文将深入探讨存储过程的应用例程,以及如何利用它来优化数据库操作。 首先,存储过程(Stored Procedure)是预编译的SQL语句集合,存储在数据库服务器中,可以被多次调用。它允许开发者封装一系列复杂的业务逻辑...
在Linux4.0内核版本下,驱动程序的开发面临着新的挑战和机遇,因为内核不断进化,提供了更高效、更灵活的框架来支持各种硬件。 在嵌入式Linux开发中,设备驱动扮演着至关重要的角色。它们是操作系统与硬件之间的...
Linux设备驱动程序是操作系统与硬件之间的一层接口,它允许操作系统和应用程序控制和通信硬件设备。本入门例程是为初学者设计的,通过实际操作和编译,可以帮助理解Linux设备驱动的基本概念和开发流程。 在提供的...
基于linux下的串口通信例程,通过向内核加载矩阵键盘的驱动,实现扫描某个键盘按下后,发送,,,。当按下另外一个按键时,发送另外一个数据。本实验已在三星6410平台上移植成功了。 请下载时注意下载键盘驱动程序
在Linux程序开发的世界里,ARM(Advanced RISC Machines...通过分析和实践这些例程,开发者可以逐步提升在Linux环境下针对ARM平台的编程能力,掌握系统级编程的核心概念和技术,为更复杂的系统级应用开发打下坚实基础。
linux sh脚本例程
基于linux下的串口通信例程,通过向内核加载矩阵键盘的驱动,实现扫描某个键盘按下后,发送。当按下另外一个按键时,发送另外一个数据。本实验已在三星6410平台上移植成功了。 此为键盘驱动程序直接加载到内核即可...
**VS2008串口例程详解** Visual Studio 2008(VS2008)是一款强大的集成开发环境,广泛应用于Windows平台上的软件开发。在VS2008中实现串口通信是许多嵌入式系统、工业设备控制、数据采集以及物联网应用中的常见...
本资源" LINUX设备驱动程序开发详解 "提供了一个全面的学习平台,帮助开发者深入理解这一核心技术。下面,我们将详细探讨Linux驱动开发的相关知识点。 首先,我们要明白Linux驱动是操作系统与硬件之间的桥梁,它...
`pci_linux.rar`这个压缩包似乎包含了与Linux系统下的PCI驱动程序相关的资源,特别是针对PCI打印机和PCI子系统的初始化例程。 PCI驱动程序是Linux内核的一部分,它允许操作系统与通过PCI总线连接的硬件设备进行通信...
这可能意味着提供的例程是针对这个特定标签下的开发板优化的,或者包含了与之相关的特定功能或改进。 压缩包内的文件名"Single_Test_V5.0.rar"可能是包含一系列独立测试例程的软件包,版本号为5.0,这样的测试例程...
### STM32官方USB例程JoyStick详解:深入解析与应用 #### 一、引言 在嵌入式开发领域,STM32作为一款广泛使用的微控制器,其强大的功能和丰富的资源使其成为许多项目的首选。其中,USB接口的集成使得STM32能够轻松...