一、前言

在学习一些项目代码时,尤其涉及到命令行传参的代码,经常遇到getopt相关的函数,对这一类函数可以说是既陌生又熟悉。陌生是因为不知道它是干啥的,熟悉呢,是因为经常遇到。于是乎在追踪了多天ipsec配置文件解析流程之后,准备学习下这一类命令行解析利器。

这么多命令行参数,需要解析,想象都让人头大,如果再没有一个好的解析方式,那就雪上加霜了。辛亏有了一类命令行解析函数,可以让这些解析操作变得容易一点点。下面就简单的介绍下这一类函数,主要有getopt、getopt_long、getopt_long_only。

Man 手册信息如下:

NAME
       getopt, getopt_long, getopt_long_only, optarg, optind, opterr, optopt - Parse command-line options SYNOPSIS
       #include <unistd.h>
       int getopt(int argc, char * const argv[],
                  const char *optstring);        extern char *optarg;
       extern int optind, opterr, optopt;        #include <getopt.h>
       int getopt_long(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);        int getopt_long_only(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

先从最简单的,最基本的getopt函数开始。然后再介绍增强版的getopt_long函数。

二、getopt函数

2.1 函数简介:

int getopt(int argc, char * const argv[], const char *optstring);

各项参数解释如下:

函数功能

用来解析命令行选项参数,只适用于短选项:-d /root; 不能解析长选项--arch, --help等

Argc

通过命令行传给main函数参数的个数

argv

通过命令行传给main函数参数组成的字符串指针数组

optstring

选项字符串。用来告诉getopt可以解析哪些选项,哪些选项需要参数以及函数返回值等(字符后面紧跟一个冒号则需要参数,而两个则表示参数可选)

返回值

如果成功返回选项字母;命令行解析完毕返回-1;如果选项未定义,则提示错误信息,并返回'?';如果参数缺失,第一个字符是':'则返回':', 否则返回'?'

对于optstring字符串格式做一个简单说明:

单个字符,表示没有参数

单个字符紧跟1个冒号,表示必须有参数,格式:-d xxx或者-dxxx

单个字符紧跟2个冒号,表示参数可选,格式:-dxxx

Char *optstring="ab:c::";

说明:此选项指定了三个选项,分别为'a'、'b'、'c'。其中

a选项无需参数,格式:-a即可

b选项必须有参数,格式:-d xxx

c选项参数可选,格式:-c ooo

在此类函数中,需要几个重要的变量共同配合才能完成命令行参数解析工作:

变量名称

作用

Char *optarg

指向当前选项参数的指针

Int optind

用来记录当前已遍历选项的索引,方便下次调用时直接找到下一个选项

Int opterr

正常情况,解析失败会有错误信息,如果不需要此错误信息,将opterr置0即可

Int optopt

最后一个未知选项

2.2 举例说明:

代码如下:


/*************************************************************************
> File Name: getopt.c
> Author: Toney
> Mail: vip_13031075266@163.com
> Created Time: 2021年01月30日 星期六 21时50分45秒
************************************************************************/ #include <stdio.h>
#include <unistd.h>
#include <getopt.h> void main(int argc, char **argv)
{
int flags, opt; while((opt = getopt(argc, argv, "ab:c::")) != -1){ switch(opt){
case 'a':
printf("Input %d parameter is -a=%s\n", optind, optarg);
break;
case 'b':
printf("Input %d parameter is -b=%s\n", optind, optarg);
break;
case 'c':
printf("Input %d parameter is -c=%s\n", optind, optarg);
break;
default:
printf("Not match!!!");
}
} return ; }

三、getopt_long函数

3.1 函数简介:

int getopt_long(int argc, char * const argv[], const char *optstring,const struct option *longopts, int *longindex);

各项参数解释如下:

函数功能

用来解析命令行选项参数,除了getopt函数支持的短选项,还支持长选项,如--help, --prefix

Argc

通过命令行传给main函数参数的个数

argv

通过命令行传给main函数参数组成的字符串指针数组

optstring

选项字符串。用来告诉getopt可以解析哪些选项,哪些选项需要参数以及函数返回值等(字符后面紧跟一个冒号则需要参数,而两个则表示参数可选)

longopts

长选项参数的名称、属性、以及解析后的返回值等结构信息

longindex

用来记录解析到的当前长选项的索引,也就是longopts的下标。

返回值

对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数

Struct option结构体:

struct option {
const char  *name;       /* 参数名称 */
int          has_arg;    /* 指明是否带有参数 */
int          *flag;      /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */
int          val;        /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
};

其中has_arg类型取值有如下几种:

No_argument

不需要参数

Required_argument

必须带参数

Optional_argument

参数可选

在此类函数中,需要几个重要的变量共同配合才能完成命令行参数解析工作:

变量名称

作用

Char *optarg

指向当前选项参数的指针

Int optind

用来记录当前已遍历选项的索引,方便下次调用时直接找到下一个选项

Int opterr

正常情况,解析失败会有错误信息,如果不需要此错误信息,将opterr置0即可

Int optopt

最后一个未知选项

3.2 ipsec项目中的一个例子:

先看看在openswan源码中,有关使用getopt_long解析命令行的一个例子(各位把住坐稳了):

static const struct option long_opts[] = {
# define OO OPTION_OFFSET
/* name, has_arg, flag, val */ { "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "optionsfrom", required_argument, NULL, '+' },
{ "label", required_argument, NULL, 'l' }, { "ctlbase", required_argument, NULL, OPT_CTLBASE + OO },
{ "name", required_argument, NULL, OPT_NAME + OO },
{ "connalias", required_argument, NULL, OPT_CONNALIAS + OO }, { "keyid", required_argument, NULL, OPT_KEYID + OO },
{ "addkey", no_argument, NULL, OPT_ADDKEY + OO },
{ "pubkeyrsa", required_argument, NULL, OPT_PUBKEYRSA + OO }, { "myid", required_argument, NULL, OPT_MYID + OO }, { "route", no_argument, NULL, OPT_ROUTE + OO },
{ "unroute", no_argument, NULL, OPT_UNROUTE + OO }, { "initiate", no_argument, NULL, OPT_INITIATE + OO },
{ "terminate", no_argument, NULL, OPT_TERMINATE + OO },
{ "delete", no_argument, NULL, OPT_DELETE + OO },
{ "deletestate", required_argument, NULL, OPT_DELETESTATE + OO + NUMERIC_ARG },
{ "crash", required_argument, NULL, OPT_DELETECRASH + OO },
{ "listen", no_argument, NULL, OPT_LISTEN + OO },
{ "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
{ "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO }, { "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
{ "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
{ "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
{ "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
{ "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO }, { "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
{ "rereadall", no_argument, NULL, OPT_REREADALL + OO },
{ "status", no_argument, NULL, OPT_STATUS + OO },
{ "shutdown", no_argument, NULL, OPT_SHUTDOWN + OO },
{ "xauthname", required_argument, NULL, OPT_XAUTHNAME + OO },
{ "xauthuser", required_argument, NULL, OPT_XAUTHNAME + OO },
{ "xauthpass", required_argument, NULL, OPT_XAUTHPASS + OO },
{ "tpmeval", required_argument, NULL, OPT_TPMEVAL + OO }, { "oppohere", required_argument, NULL, OPT_OPPO_HERE + OO },
{ "oppothere", required_argument, NULL, OPT_OPPO_THERE + OO }, { "asynchronous", no_argument, NULL, OPT_ASYNC + OO }, /* list options */ { "utc", no_argument, NULL, LST_UTC + OO },
{ "checkpubkeys", no_argument, NULL, LST_CHECKPUBKEYS + OO },
{ "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
{ "listcerts", no_argument, NULL, LST_CERTS + OO },
{ "listcacerts", no_argument, NULL, LST_CACERTS + OO },
{ "listacerts", no_argument, NULL, LST_ACERTS + OO },
{ "listaacerts", no_argument, NULL, LST_AACERTS + OO },
{ "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
{ "listgroups", no_argument, NULL, LST_GROUPS + OO },
{ "listcrls", no_argument, NULL, LST_CRLS + OO },
{ "listocsp", no_argument, NULL, LST_OCSP + OO },
{ "listpsks", no_argument, NULL, LST_PSKS + OO },
{ "listevents", no_argument, NULL, LST_EVENTS + OO },
{ "listpairs", no_argument, NULL, LST_HOSTPAIRS + OO },
{ "listhostpairs", no_argument, NULL, LST_HOSTPAIRS + OO },
{ "listall", no_argument, NULL, LST_ALL + OO }, /* options for an end description */ { "host", required_argument, NULL, END_HOST + OO },
{ "id", required_argument, NULL, END_ID + OO },
{ "cert", required_argument, NULL, END_CERT + OO },
{ "ca", required_argument, NULL, END_CA + OO },
{ "groups", required_argument, NULL, END_GROUPS + OO },
{ "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
{ "nexthop", required_argument, NULL, END_NEXTHOP + OO },
{ "client", required_argument, NULL, END_CLIENT + OO },
{ "clientwithin", required_argument, NULL, END_CLIENTWITHIN + OO },
{ "clientprotoport", required_argument, NULL, END_CLIENTPROTOPORT + OO },
{ "dnskeyondemand", no_argument, NULL, END_DNSKEYONDEMAND + OO },
{ "srcip", required_argument, NULL, END_SRCIP + OO },
{ "updown", required_argument, NULL, END_UPDOWN + OO },
{ "tundev", required_argument, NULL, END_TUNDEV + OO + NUMERIC_ARG }, /* options for a connection description */ { "to", no_argument, NULL, CD_TO + OO }, { "psk", no_argument, NULL, CD_PSK + OO },
{ "rsasig", no_argument, NULL, CD_RSASIG + OO }, { "encrypt", no_argument, NULL, CD_ENCRYPT + OO },
{ "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO },
{ "compress", no_argument, NULL, CD_COMPRESS + OO },
{ "overlapip", no_argument, NULL, CD_OVERLAPIP + OO },
{ "tunnel", no_argument, NULL, CD_TUNNEL + OO },
{ "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
{ "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
{ "pfs", no_argument, NULL, CD_PFS + OO },
{ "sha2_truncbug", no_argument, NULL, CD_SHA2_TRUNCBUG + OO },
{ "aggrmode", no_argument, NULL, CD_AGGRESSIVE + OO },
{ "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
{ "initiateontraffic", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "pass", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_PASS >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "drop", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_DROP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "reject", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_REJECT >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "failnone", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_NONE >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "failpass", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_PASS >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "faildrop", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_DROP >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "failreject", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
{ "forceencaps", no_argument, NULL, CD_FORCEENCAPS + OO },
{ "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
{ "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
{ "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
#ifdef XAUTH
{ "xauth", no_argument, NULL, END_XAUTHSERVER + OO },
{ "xauthserver", no_argument, NULL, END_XAUTHSERVER + OO },
{ "xauthclient", no_argument, NULL, END_XAUTHCLIENT + OO },
#endif
#ifdef MODECFG
{ "modecfgpull", no_argument, NULL, CD_MODECFGPULL + OO },
{ "modecfgserver", no_argument, NULL, END_MODECFGSERVER + OO },
{ "modecfgclient", no_argument, NULL, END_MODECFGCLIENT + OO },
#ifdef MODECFG_DNSWINS
{ "modecfgdns1", required_argument, NULL, CD_MODECFGDNS1 + OO },
{ "modecfgdns2", required_argument, NULL, CD_MODECFGDNS2 + OO },
{ "modecfgwins1", required_argument, NULL, CD_MODECFGWINS1 + OO },
{ "modecfgwins2", required_argument, NULL, CD_MODECFGWINS2 + OO },
{ "modeconfigserver", no_argument, NULL, END_MODECFGSERVER + OO },
{ "modeconfigclient", no_argument, NULL, END_MODECFGCLIENT + OO },
#endif
#endif
{ "metric", required_argument, NULL, CD_METRIC + OO + NUMERIC_ARG },
{ "mtu", required_argument, NULL, CD_CONNMTU + OO + NUMERIC_ARG },
{ "sendcert", required_argument, NULL, END_SENDCERT + OO },
{ "certtype", required_argument, NULL, END_CERTTYPE + OO + NUMERIC_ARG },
{ "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
{ "ipv6", no_argument, NULL, CD_CONNIPV6 + OO }, { "ikelifetime", required_argument, NULL, CD_IKELIFETIME + OO + NUMERIC_ARG },
{ "ipseclifetime", required_argument, NULL, CD_IPSECLIFETIME + OO + NUMERIC_ARG },
{ "rekeymargin", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG },
{ "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
{ "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
{ "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
{ "ike", required_argument, NULL, CD_IKE + OO },
{ "ikealg", required_argument, NULL, CD_IKE + OO },
{ "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
{ "esp", required_argument, NULL, CD_ESP + OO },
{ "remote_peer_type", required_argument, NULL, CD_REMOTEPEERTYPE + OO},
#ifdef HAVE_NM
{ "nm_configured", no_argument, NULL, CD_NMCONFIGURED + OO},
#endif
#ifdef HAVE_LABELED_IPSEC
{ "loopback", no_argument, NULL, CD_LOOPBACK + OO},
{ "labeledipsec", no_argument, NULL, CD_LABELED_IPSEC + OO},
{ "policylabel", required_argument, NULL, CD_POLICY_LABEL + OO },
#endif
#ifdef DEBUG
{ "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
{ "debug-all", no_argument, NULL, DBGOPT_ALL + OO },
{ "debug-raw", no_argument, NULL, DBGOPT_RAW + OO },
{ "debug-crypt", no_argument, NULL, DBGOPT_CRYPT + OO },
{ "debug-parsing", no_argument, NULL, DBGOPT_PARSING + OO },
{ "debug-emitting", no_argument, NULL, DBGOPT_EMITTING + OO },
{ "debug-control", no_argument, NULL, DBGOPT_CONTROL + OO },
{ "debug-lifecycle", no_argument, NULL, DBGOPT_LIFECYCLE + OO },
{ "debug-klips", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-netkey", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-xfrm", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-dns", no_argument, NULL, DBGOPT_DNS + OO },
{ "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
{ "debug-oppoinfo", no_argument, NULL, DBGOPT_OPPOINFO + OO },
{ "debug-whackwatch", no_argument, NULL, DBGOPT_WHACKWATCH + OO },
{ "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
{ "debug-pfkey", no_argument, NULL, DBGOPT_PFKEY + OO },
{ "debug-nattraversal", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-natt", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-nat_t", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-nat-t", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-x509", no_argument, NULL, DBGOPT_X509 + OO },
{ "debug-dpd", no_argument, NULL, DBGOPT_DPD + OO },
{ "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO }, { "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
{ "impair-delay-adns-txt-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER + OO },
{ "impair-bust-mi2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MI2 + OO },
{ "impair-bust-mr2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MR2 + OO },
{ "impair-sa-fail", no_argument, NULL, DBGOPT_IMPAIR_SA_CREATION + OO },
{ "impair-die-oninfo", no_argument, NULL, DBGOPT_IMPAIR_DIE_ONINFO + OO },
{ "impair-jacob-two-two", no_argument, NULL, DBGOPT_IMPAIR_JACOB_TWO_TWO + OO },
{ "impair-major-version-bump", no_argument, NULL, DBGOPT_IMPAIR_MAJOR_VERSION_BUMP + OO },
{ "impair-minor-version-bump", no_argument, NULL, DBGOPT_IMPAIR_MINOR_VERSION_BUMP + OO },
{ "impair-retransmits", no_argument, NULL, DBGOPT_IMPAIR_RETRANSMITS + OO },
{ "impair-send-bogus-isakmp-flag", no_argument, NULL, DBGOPT_IMPAIR_SEND_BOGUS_ISAKMP_FLAG + OO },
{ "whackrecord", required_argument, NULL, OPT_WHACKRECORD + OO},
{ "whackstoprecord", no_argument, NULL, OPT_WHACKSTOPRECORD + OO},
#endif
# undef OO
{ 0,0,0,0 }
};

这是whack命令解析时的一个结构信息,可以想象它的配置命令是有多少,而具体实现差不多800行左右的C代码。这里需要注意的是:struct option结构中的val取值通常是单个字符或者数字。由于单字符数量有限,参数比较少时可以使用字符,但是如果像上面辣么多参数,通常采用枚举类型,方便扩展。

四、getopt_long_only函数

getopt_long_only 函数与 getopt_long 函数使用相同的参数表,在功能上基本一致,只是 getopt_long 只将 --name 当作长参数,但 getopt_long_only 会将 --name 和 -name 两种选项都当作长参数来匹配。getopt_long_only 如果选项 -name 不能在 longopts 中匹配,但能匹配一个短选项,它就会解析为短选项。

命令行解析函数:getopt_long、getopt的更多相关文章

  1. C语言命令行解析函数:getopt/getopt_long

    命令行工具下的参数选项有两种,长选项和短选项.短选项以-开头,后面跟单个字母:长选项以--开头,后面可跟多个字母. 一. getopt() 1.功能:解析命令行短选项参数 2.函数原型: #inclu ...

  2. 命令行解析函数:getopt/getopt_long

    参考: http://blog.csdn.net/zhangyang0402/article/details/5671410 http://www.cnblogs.com/gnuhpc/archive ...

  3. 【C】命令行参数解析——getopt、getopt_long及getopt_long_only

    前言 在linux下学习开源代码Webbench,遇到get_long等函数的用法,一时有点懵,故想深入了解这类命令行解析函数,并记此博文. 1.getopt getopt主要用来处理短命令行选项,例 ...

  4. [转]Python 命令行参数和getopt模块详解

    FROM : http://www.tuicool.com/articles/jaqQvq 有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Pyt ...

  5. Python 命令行参数和getopt模块详解

    有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Python里,命令行的参数和C语言很类似(因为标准Python是用C语言实现的).在C语言里,m ...

  6. linux 中解析命令行参数(getopt_long用法)

    linux 中解析命令行参数(getopt_long用法) http://www.educity.cn/linux/518242.html 详细解析命令行的getopt_long()函数 http:/ ...

  7. shell 命令行参数(getopt和getopts)

    getopt 命令 使用getopt命令,可以解析任何命令行选项和参数,但是用法比较复杂.getopt的命令用法如下: $ getopt --help 用法: getopt optstring par ...

  8. 命令行参数处理-getopt()和getopt_long()

    在实际编程当中,自己编写代码处理命令行参数是比较麻烦且易出错的.一般我们会直接使用getopt()和getopt_long()函数,下文将介绍具体的使用方法. getopt() getopt()用于处 ...

  9. 命令行解析getopt_long

    getopt_long函数可以轻松的解析main函数的命令行参数. int getopt_long(int argc,char * const argv[],const char *optstring ...

随机推荐

  1. 从 HTTP 切换到 HTTPS,这下我的技术博客安全了吧?

    博客园 的小伙伴们,大家好,我是刚脱离险境的二哥呀! 很久(大概两年)之前,我就搞了一个独立的个人博客网站,长下面这样. 大家有访问过的,可以在评论区扣 1 可惜一直没搞备案和 HTTPS,导致每次访 ...

  2. Mybatis学习笔记-配置解析

    核心配置文件 mybatis-config.xml properties(属性) settings(设置) typeAliases(类型别名) typeHandlers(类型处理器) objectFa ...

  3. Python中print()函数的用法

    print()函数用于打印输出 1.函数语法: print(values,sep=' ',end='\n') sep和end是print()函数常用参数 参数sep是一次打印多个元素时的间隔符号,默认 ...

  4. Linux系统CPU信息查询方法

    lscpu cat /proc/cpuinfo对绝大多数Linux适用,lscpu更简练 cat /proc/cpuinfo 下面是一个实例: processor : 0 vendor_id : Ge ...

  5. Linux进程理解与实践(一)基本概念和编程概述(fork,vfork,cow)

    进程 and 程序 什么是程序? 程序是完成特定任务的一系列指令集合. 什么是进程? [1]从用户的角度来看:进程是程序的一次执行过程 [2]从操作系统的核心来看:进程是操作系统分配的内存.CPU时间 ...

  6. kivy之Label属性及文本标记实操练习

    关于kivy内label功能有二部分内容,一个是label小部件属性,另一个是label文本标记属性,实操练习的效果图如下: . 现将label常用的这二类属性整理如下: 现在我们来进行实操练习,在p ...

  7. ReentrantLock中的Condition(等待和唤醒)

    Condition 类的 awiat 方法和 Object 类的 wait 方法等效 Condition 类的 signal 方法和 Object 类的 notify 方法等效 Condition 类 ...

  8. adobe cc 系列产品更改默认安装路径方法

    通过Adobe Creative Cloud 修改 1.在开始菜单中找到图下程序点开,并进行如下操作: 2.点击Apps位置 等待加载出软件,如图下所示. 点击右上角图标,会弹出以下窗口,点击首选项 ...

  9. 如何使用Git建立本地仓库并上传代码到GitHub

    使用Git建立本地仓库并上传代码到GitHub 工具/原料   电脑安装git客户端.注册github账号并登陆 方法/步骤     到本地项目文件夹右键选择git bash here   输入个人信 ...

  10. Jmeter HTML 报告、Jenkins 配置

    目录 Jmeter 生成 HTML 测试报告 Jenkins 配置 Jmeter 生成 HTML 测试报告 JMeter 支持生成 HTML 测试报告, 以便从测试计划中获得图表和统计信息. 以上定义 ...