函数对象

看到有个概念叫“函数对象”,搜了一下关于它的解释:


数对象(function 
object),又名仿函数(functor),是重载了operator()的一个类,其实在stl算法中有大量运用,c++标准预定义的如
less <>,greater <>,bind2nd <>等 
  为什么引入仿函数? 
  原因: 
  1.仿函数有具体型别,可用在模板参数,而函数不行 
  2.同类仿函数可有不同植,可代表不同状态,比函数灵活(须定义多个) 
  3.仿函数可能比普通函数快 
  ........可能还有,不过凭印象就这些了

  和普通函数相比,在不破坏接口的情况下,函数对象可以有自己的状态.

另外,

1 什么是函数对象

c++在模板方面使用很多的一个技术,写一个类,这个类有个成员函数,可以让类象函数一样运行。
主要用于模板函数中。

2 实现

类的成员函数,()可以让一个类运行起来象一个函数一样,如我们在排序的时候我们使用sort
可能sort是这样的sort(int, int)
我们自己可以写一个类,其中重载void operator()(int, int)来实现。

for_each(begin, end, func)
这个func如果是函数的话,会把value(*it)放在函数的参数位置上,如果是一个类在那个位置,将会调用运算符函数()来将参数传递进去。首先调用构造函数,构造函数初始化一个对象后,对象调用函数()来实现函数对象操作。

3 函数对象的优势

函数对象的功能于函数的功能是一样的,那为什么要使用默认构造函数。
1 函数对象是一个智能对象,他可以利用对象中的成员函数,和成员变量。
2 完全可以使用类的优势,可以使用类的重载特性,同样的一个类的名字,可以调用各种函数。

more exceptional c++The C++ Programming Language等书里有看到。

函数对象示例:

  1. // Negate.cpp
  2. #include <iostream>
  3. using namespace std;
  4.  
  5. class Negate
  6. {
  7. public:
  8.        template<class T> T operator()(T t) const
  9.        {
  10.               return -t;
  11.        }
  12. };
  13. void Callback(int n, const Negate& neg)  // 传递一个函数对象
  14. {
  15.        n = neg(n);  // 调用重载的 () 操作 来对 n 进行 negate 操作
  16.        cout << n << endl;
  17. }
  18. int main(int argc, char* argv[])
  19. {
  20.        // 调用方式一
  21.        Callback(5, Negate());
  22.        // 调用方式二
  23.        Negate neg;
  24.        cout << neg(9.99999) << endl;      
  25.        cout << neg(__int32(39999999)) << endl;
  26.        getchar();
  27.        return 0;
  28. }

PS:

定义函数对象

时间:2001/02/07 15:22 作者:vckbase VC知识库


  尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“算符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。

用函数对象代替函数指针有几个优点,首先,因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用
结果的数据成员。在使用普通函数时需要将先前调用的结果存储在全程或者本地静态变量中,但是全程或者本地静态变量有某些我们不愿意看到的缺陷。

其次,在函数对象中编译器能实现内联调用,从而更进一步增强了性能。这在函数指针中几乎是不可能实现的。

下面举例说明如何定义和使用函数对象。首先,声明一个普通的类并重载“()”操作符:

class Negate

{

public:

int operator() (int n) { return -n;}

};

重载操作语句中,记住第一个圆括弧总是空的,因为它代表重载的操作符名;第二个圆括弧是参数列表。一般在重载操作符时,参数数量是固定的,而重载“()”操作符时有所不同,它可以有任意多个参数。

因为在Negate中内建的操作是一元的(只有一个操作数),重载的“()”操作符也只有一个参数。返回类型与参数类型相同-本例中为int。函数返回与参数符号相反的整数。

使用函数对象

我们现在定义一个叫Callback()的函数来测试函数对象。Callback()有两个参数:一个为int一个是对类Negate的引用。Callback()将函数对象neg作为一个普通的函数名:

#include

using std::cout;

void Callback(int n, Negate & neg)

{

int val = neg(n); //调用重载的操作符“()”

cout << val;

}

不要的代码中,注意neg是对象,而不是函数。编译器将语句

int val = neg(n);

转化为

int val = neg.operator()(n);

通常,函数对象不定义构造函数和析构函数。因此,在创建和销毁过程中就不会发生任何问题。前面曾提到过,编译器能内联重载的操作符代码,所以就避免了与函数调用相关的运行时问题。

为了完成上面个例子,我们用主函数main()实现Callback()的参数传递:

int main()

{

Callback(5, Negate() ); //输出 -5

}

本例传递整数5和一个临时Negate对象到Callback(),然后程序输出-5。

模板函数对象

从上面的例子中可以看出,其数据类型被限制在int,而通用性是函数对象的优势之一,如何创建具有通用性的函数对象呢?方法是使用模板,也就是将重载的操作符“()”定义为类成员模板,以便函数对象适用于任何数据类型:如double,_int64或char:

class GenericNegate

{

public:

template T operator() (T t) const {return -t;}

};

int main()

{

GenericNegate negate;

cout<< negate(5.3333); // double

cout<< negate(10000000000i64); // __int64

}

如果用普通的回调函数实现上述的灵活性是相当困难的。

标准库中函数对象

C++标准库定义了几个有用的函数对象,它们可以被放到STL算法中。例如,sort()算法以判断对象(predicate
object)作为其第三个参数。判断对象是一个返回Boolean型结果的模板化的函数对象。可以向sort()传递greater<>或
者less<>来强行实现排序的升序或降序:

#include // for greater<> and less<>

#include //for sort()

#include

using namespace std;

int main()

{

vector vi;

//..填充向量

sort(vi.begin(), vi.end(), greater() );//降序( descending )

sort(vi.begin(), vi.end(), less() ); //升序 ( ascending )

}

C语言函数中定义大数组耗尽堆栈的问题

今晚上一同学请我帮忙看一个C程序,GCC编译时一直抱错,说是段错误。
程序本身写的比较差,但编译能通过,只是有几十个警告。
两个小时过去了,在Eclipse+GCC下没有找到问题(这个环境还不熟悉),换到了VC下面,逐步调试,才发现问题出在被main调用的一个叫做readmctal()的函数的前面几行中。该函数如下:

  1. void readmctal(void)
  2. {
  3.     int number,count,sign,num_tally,nflag;
  4.     int ncell,nstep,mstep,sum;
  5.     char *(str_temp[80]);
  6.     float temp_spectra[num_cell][egroup],temp_error[num_cell][egroup];
  7. float temp_flux[num_cell],temp_flux_error[num_cell];
  8.     int total_cell_no[num_cell];
  9.     sum=0;  
  10.     number=0;
  11.     /* open the mctal file */
  12.     if ((fpt_mc=fopen("mctal","r"))==NULL){
  13.         printf("/nERROR - Cannot open mctal file/n");
  14.         exit(1);
  15.     }
  16.     else
  17.     {
  18.         printf("File mctal opened.../n");
  19.     }
  20.     ......

同时

  1. # define num_cell 9999
  2. # define egroup 175

定义的二位数组实在是太大了。看了反汇编之后感觉貌似是堆栈的问题,试着将
float temp_spectra[num_cell][egroup],temp_error[num_cell][egroup];
float temp_flux[num_cell],temp_flux_error[num_cell];
移动到函数体外,大功告成!
到Linux下用GCC编译,“段错误”的提示消失了。

经过分析,我认为一个函数分配的内存是有限的,在函数体内定义的二维数组太大了,耗尽了堆栈,因此报错。

PS:论坛达人的观点:
养成良好的编程习惯,一般公司都有coding style,里面应该有规定:
函数内部(局部变量)禁止定义大数组,而应使用动态内存;如数组需传入函数应使用指针作为参数;
其实就算你调用这个函数不出错,但是如果函数嵌套很多的话也会发生segment error
在某些资源有限的系统下,更需要注意这个问题,比如51单片机

函数内是在栈分配内存,栈大小一般限制在1M到2M
函数外则是全局变量,在DATA段分配内存

PSPS:转一篇关于C内存分配的文章,原文链接http://www.lupaworld.com/bbs/viewthread.php?tid=29577

浅谈C内存分配

很早之前写的了,现在发到C版来。

关于C语言内存方面的话题要真说起来的话那恐怕就没头了,所以本文仅仅是一个浅谈。
关于内存问题不同平台之间有一定的区别。本文所指的平台是x86的Linux平台
用C语言做程序(其实其他语言也一样),不仅要熟悉语法,其实很多相关的背景知识也很重要。在学习和研究C语言中内存分配的问题前,首先要了解一下Linux分配给进程(运行中的程序)的地址空间是什么样的。
总的来说有3个段,即代码段,数据段和堆栈段(学过汇编的朋友一定很熟悉了)。代码段就是存储程序文本的,所以有时候也叫做文本段,指令指针中的指令就是
从这里取得。这个段一般是可以被共享的,比如你在Linux开了2个Vi来编辑文本,那么一般来说这两个Vi是共享一个代码段的,但是数据段不同(这点有
点类似C++中类的不同对象共享相同成员函数)。数据段是存储数据用的,还可以分成初始化为非零的数据区,BSS,和堆(Heap)三个区域。初始化非零
数据区域一般存放静态非零数据和全局的非零数据。BSS是Block Started by
Symbol的缩写,原本是汇编语言中的术语。该区域主要存放未初始化的全局数据和静态数据。还有就是堆了,这个区域是给动态分配内存是使用的,也就是用
malloc等函数分配的内存就是在这个区域里的。它的地址是向上增长的。最后一个堆栈段(注意,堆栈是Stack,堆是Heap,不是同一个东西),堆
栈可太重要了,这里存放着局部变量和函数参数等数据。例如递归算法就是靠栈实现的。栈的地址是向下增长的。具体如下:
========高地址     =======
程序栈             堆栈段
         向下增长
“空洞”           =======
         向上增长

------             数据段
BSS
------
非零数据
=========低地址    =======
=========          =======
代码               代码段
=========          =======
需要注意的是,代码段和数据段之间有明确的分隔,但是数据段和堆栈段之间没有,而且栈是向下增长,堆是向上增长的,因此理论上来说堆和栈会“增长到一起”,但是操作系统会防止这样的错误发生,所以不用过分担心。
有了以上理论做铺垫,下面就说动态内存的分配。上面说了,动态内存空间是在堆中分配的。实现动态分配的也就是下面几个函数:
stdlib.h :
void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);
一个一个说吧。malloc就是分配一个size大小的内存空间,并且用一个void类型的指针指向这个空间,然后返回这个指针。也就是说,malloc
返回了一个指向size大小的空间的void类型的指针,如果要使用这个空间,还得把void*类型转换成一个你需要的类型,比如int*之类。
calloc和malloc基本一样,不同的是有两点,一是calloc分配的空间大小是由nmemb*size决定的,也就是说nmemb是条目个数,
而size可以看成是条目的大小,计算总空间任务由calloc去做。二是calloc返回的空间都用0填充,而malloc则不确定内存中会有什么东
西。realloc是用来改变已经分配的空间的大小。指针ptr是void类型的,它应该指向一个需要重新分配大小的空间,而size参数则是重新分配之
后的整个空间大小,而不是增加的大小。同样,返回的是一个指向新空间的指针。free用来释放由上面3个函数分配的空间,其参数就是指向某空间的指针。
基本就这些了,这些都是比较基础的话题,高级话题和细节问题还有很多,这里就不进行说明了,有机会我会继续总结一番的

《UNIX教程》读书笔记(一)

《UNIX教程》读书笔记

Part I    UNIX Shell

1 文件类型

  • d 目录。
  • l 符号链接(指向另一个文件)。
  • s 套接字文件。
  • b 块设备文件。
  • c 字符设备文件。
  • p 命名管道文件。
  • - 普通文件,或者更准确地说,不属于以上几种类型的文件。

2 该变权限位
chmod命令的一般格式为:
    chmod [who] operator [permission] filename
w h o的含义是:
u 文件属主权限。
g 同组用户权限。
o 其他用户权限。
a 所有用户(文件属主、同组用户及其他用户)。
o p e r a t o r的含义:
+ 增加权限。
- 取消权限。
= 设定权限。
p e r m i s s i o n的含义:
r 读权限。
w 写权限。
x 执行权限。
s 文件属主和组s e t - I D。
t 粘性位*。
l 给文件加锁,使其他用户无法访问。
u,g,o 针对文件属主、同组用户及其他用户的操作。

chmod命令绝对模式的一般形式为:
chmod [mode] file
其中m o d e是一个八进制数。

3 目录
目录的读权限位意味着可以列出其中的内容。写权限位意味着可以在该目录中创建文件,如果不希望其他用户在你的目录中创建文件,可以取消相应的写权限位。执行权限位则意味着搜索和访问该目录。

如果把同组用户或其他用户针对某一目录的权限设置为- - x,那么他们将无法列出该目录中的文件。如果该目录中有一个执行位置位的脚本或程序,只要用户知道它的路径和文件名,仍然可以执行它。用户不能够进入该目录并不妨碍他的执行。

目录的权限将会覆盖该目录中文件的权限。

4 suid/guid
suid
意味着如果某个用户对属于自己的shell脚本设置了这种权限,那么其他用户在执行这一脚本时也会具有其属主的相应权限。于是,如果根用户的某一个脚本设
置了这样的权限,那么其他普通用户在执行它的期间也同样具有根用户的权限。同样的原则也适用于guid,执行相应脚本的用户将具有该文件所属用户组中用户
的权限。

有相当一些U N I X命令也设置了s u i d和g u i d。如果想找出这些命令,可以进入/ b i n或/ s b i n目
录,执行下面的命令:
$ ls -l | grep '^...s'
上面的命令是用来查找s u i d文件的;
$ ls -l | grep '^...s..s'
上面的命令是用来查找s u i d和g u i d的。

如果希望设置s u i d,那么就将相应的权限位之前的那一位设置为4;如果希望设置g u i d,那么就将相应的权限
位之前的那一位设置为2;如果希望两者都置位,那么将相应的权限位之前的那一位设置为4+2。
一旦设置了这一位,一个s将出现在x的位置上。记住:在设置s u i d或g u i d的同时,相应的
执行权限位必须要被设置。例如,如果希望设置g u i d,那么必须要让该用户组具有执行权限。
如果想要对文件l o g i n设置s u i d,它当前所具有的权限为rwx rw- r-- (741),需要在使用
c h m o d命令时在该权限数字的前面加上一个4,即chmod 4741,这将使该文件的权限变为rws
rw- r - -。
$ chmod 4741 logit

还可以使用符号方式来设置s u i d / g u i d。如果某个文件具有这样的权限: rwx r-x r- x,那么
可以这样设置其s u i d:
chmod u+s <filename>
于是该文件的权限将变为: rws r-x r-x
在查找设置了s u i d的文件时,没准会看到具有这样权限的文件:rwS r-x r- x,其中S为大写。
它表示相应的执行权限位并未被设置,这是一种没有什么用处的s u i d设置,可以忽略它的存在。

在改变一个文件的所有权时,相应的suid也将被清除,这是出于安全性的考虑。

5 chown和chgrp
chown命令的一般形式为:
    chmod -R -h owner file
-R选项意味着对所有子目录下的文件也都进行同样的操作。- h选项意味着在改变符号链接文件的属主时不影响该链接所指向的目标文件。
c h g r p命令和c h o w n命令的格式差不多.

如果你希望知道自己属于哪些用户组,可以用group或id命令。如果要查看其他用户所属于的组,可以用命令group XXX,XXX是某个用户名。

6 umask
umask命令确定了你创建文件的缺省模式.一般来说,u m a s k命令是在/ e t c / p r o f i l e文件中设置的,每个用户在登录时都会引用这个文
件,所以如果希望改变所有用户的u m a s k,可以在该文件中加入相应的条目。如果希望永久性
地设置自己的u m a s k值,那么就把它放在自己$ H O M E目录下的. p r o f i l e或. b a s h _ p r o f i l e文件中。

表1-8 umask值与权限
umask     文件    目录
0             6         7
1             6         6
2             4         5
3             4         4
4             2         3
5             2         2
6             0         1
7             0         0

7 符号链接(软连接)
该命令的一般形式为:
ln [-s] source_path target_path
其中的路径可以是目录也可以是文件。

8 find命令
find命令的一般形式为:
    find pathname -options [-print -exec -ok]

让我们来看看该命令的参数:
pathname find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。
-print find命令将匹配的文件输出到标准输出。
-exec find命令对匹配的文件执行该参数所给出的s h e l l命令。相应命令的形式为' command' {} /;,注意{ }和/;之间的空格。
-ok 和- exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,
在执行每一个命令之前,都会给出提示,让用户来确定是否执行。

find命令有很多选项或表达式,每一个选项前面跟随一个横杠-。
    -name 按照文件名查找文件。
    -perm 按照文件权限来查找文件。在使用这一选项的时候,最好使用八进制的权限表示法。$ find . -perm 755 -print
    -prune 使用这一选项可以使f i n d命令不在当前指定的目录中查找,如果同时使用了-depth选项,那么-prune选项将被find命令忽略。
    -user 按照文件属主来查找文件。
    -group 按照文件所属的组来查找文件。
    -mtime
-n +n 按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+
n表示文件更改时间距现在n天以前。Find命令还有-atime和-ctime选项,但它们都和-mtime选项相似,所以我们在这里只介绍
-mtime选项。
    -nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
    -nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
    -newer file1 ! file2 查找更改时间比文件f i l e 1新但比文件f i l e 2旧的文件。
    -type 查找某一类型的文件,诸如:
        b - 块设备文件。
        d - 目录。
        c - 字符设备文件。
        p - 管道文件。
        l - 符号链接文件。
        f - 普通文件。
    -size n[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
    -depth 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
    -fstype 查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
    -mount 在查找文件时不跨越文件系统m o u n t点。
    -follow 如果f i n d命令遇到符号链接文件,就跟踪至链接所指向的文件。
    -cpio 对匹配的文件使用c p i o命令,将这些文件备份到磁带设备中。

Fedora 9安装星际译王(stardict)

Fedora 9安装星际译王(stardict)

一直苦于Linux下没有好用的翻译软件,一直再用Google的在线辞典,感觉还好。但Google在线词典最大的问题就是不能屏幕取词,而且用起来也不怎么方便,于是下决心找到一款比较好的翻译软件。

Google了一下,发现了星际译王的口碑不错,于是去http://stardict.sourceforge.net/cn/download.php 上下了一个rpm安装包,结果安装时报错:

rpm -ivh stardict-3.0.1-1.fc8.i386.rpm
error: Failed dependencies:
        espeak is needed by stardict-3.0.1-1.fc8.i386
        libespeak.so.1 is needed by stardict-3.0.1-1.fc8.i386

又下了.bz2的安装包,./configure时有N多错误。幼小的心灵倍受打击,深感国产Linux软件之不专业。

正郁闷之时,忽见网上有人说用yum安装。于是打开终端输入 yum install stardict,没想到竟然成功安装了!根本不需要特殊配置。

然后又下载了可用于星际译王的朗道英汉、汉英辞典,rpm安装,一切顺利。

试着在终端敲入 stardict运行了一下,界面很漂亮,效果很不错。顿时感觉国产开源软件还是有希望的。

谢谢胡正等前辈!

CDMA2000 Channel Naming Conventions

CDMA2000 Channel Naming Conventions

 Many
cdma2000 standards refer to logical channels, physical channels, or
both. The following naming conventions apply to all cdma2000 standards.

 1 Logical Channel Naming Convention
 A logical channel name consists of three lower case letters followed by “ch” (channel). A hyphen is
 used after the first letter. Table 1Table 1shows the naming conventions for the logical channels that
 are used in this family of standards.

 Table 1. Naming Conventions for Logical Channels
    First Letter        Second Letter         Third letter
    f = Forward       d = Dedicated         t = Traffic
    r = Reverse        c = Common        s = Signaling

 For example, the logical channel name for the Forward Dedicated Traffic Channel is f-dtch.

2 Physical Channel Naming Convention
 Physical channels are represented by upper case abbreviations. As in the case of logical channels,
 the first letters in the names of the channels indicate the direction of the channel (i.e., forward or
 reverse) and is followed by a hyphen. Table 2Table 2 shows the names and meanings of all the
 physical channels designated in cdma2000.

Table 2. Physical Channel Names
    Channel Name1            Physical Channel
    F/R-FCH                 Forward/Reverse Fundamental Channel
    F/R-DCCH               Forward/Reverse Dedicated Control Channel
    F/R-SCCH               Forward/Reverse Supplemental Code Channel
    F/R-SCH                 Forward/Reverse Supplemental Channel
    F-PCH                     Paging Channel
    F-QPCH                 Quick Paging Channel
    R-ACH                     Access Channel
    F/R-CCCH               Forward/Reverse Common Control Channel
    F/R-PICH                 Forward/Reverse Pilot Channel
    F-APICH                 Dedicated Auxiliary Pilot Channel
    F-TDPICH                 Transmit Diversity Pilot Channel
    F-ATDPICH             Auxiliary Transmit Diversity Pilot Channel
    F-SYNCH                 Sync Channel
    F-CPCCH                 Common Power Control Channel
    F-CACH                 Common Assignment Channel
    R-EACH                 Enhanced Access Channel
    F-BCCH                 Broadcast Control Channel
    F-PDCH                 Forward Packet Date Channel
    F-PDCCH                 Forward Packet Data Control Channel
    R-ACKCH                 Reverse Acknowledgement Channel
    R-CQICH                 Reverse Channel Quality Indicator Channel
    F-ACKCH                 Forward Acknowledgement Channel
    F-GCH                     Forward Grant Channel
    F-RCCH                 Forward Rate Control Channel
    R-PDCH                 Reverse Packet Data Channel
    R-PDCCH                 Reverse Packet Data Control Channel
    R-REQCH                 Reverse Request Channel

1 The notations “F/R” and “Forward/Reverse” represent two different
physical channels (i.e., one forward channel and one reverse
channel)

For example, the physical channel name for the Forward Fundamental Channel is F-FCH.

References:
 3GPP2 C.S0001-D v2.0

《Advanced Programming in the UNIX Environment》读书笔记(2)

8UNIX Standards

·       ISO C

            In late 1989, ANSI Standard X3.1591989 for the C programming language was approved. This standard has also been adopted as international standard ISO/IEC 9899:1990.             In 1999, the ISO C standard was updated and approved as ISO/IEC 9899:1999, largely to improve support for applications that perform numerical processing.


·       IEEE POSIX


·       ISO/IEC 9945-1 (IEEE Standard 1003.1-1996), which includes

                   IEEE Standard 1003.1-1990                    IEEE Standard 1003.1b-1993 (real-time extensions)                    IEEE Standard 1003.1c-1995 (pthreads)                    IEEE Standard 1003.1i-1995 (real-time technical corrigenda)

·       IEEE P1003.1a draft standard (system interface revision)

·       IEEE Standard 1003.1d-1999 (advanced real-time extensions)

·       IEEE Standard 1003.1j-2000 (more advanced real-time extensions)

·       IEEE Standard 1003.1q-2000 (tracing)

·       IEEE Standard 1003.2d-1994 (batch extensions)

·       IEEE P1003.2b draft standard (additional utilities)

·       Parts of IEEE Standard 1003.1g-2000 (protocol-independent interfaces)

·       ISO/IEC 9945-2 (IEEE Standard 1003.2-1993)

·       The Base Specifications of the Single UNIX Specification, version 2, which include

·      System Interface Definitions, Issue 5

·      Commands and Utilities, Issue 5

·      System Interfaces and Headers, Issue 5

·       Open Group Technical Standard, Networking Services, Issue 5.2

·       ISO/IEC 9899:1999, Programming Languages - C




·       The Single UNIX Specification


              A superset of the POSIX.1 standard, specifies additional interfaces that extend the functionality provided by the basic POSIX.1 specification.


·       FIPS


        


9The header <sys/types.h> defines some implementation-dependent data types, called theprimitive system data types. More of these data types are defined in other headers also. These data types are defined in the headers with the C typedef facility. Most end in _t.                   Figure 2.20. Some common primitive system data types              Type                                                       Description caddr_t                     core address (Section 14.9) clock_t                     counter of clock ticks (process time) (Section 1.10) comp_t                      compressed clock ticks (Section 8.14) dev_t                       device numbers (major and minor) (Section 4.23) fd_set                      file descriptor sets (Section 14.5.1) fpos_t                      file position (Section 5.10) gid_t                       numeric group IDs ino_t                       i-node numbers (Section 4.14) mode_t                      file type, file creation mode ( ection 4.5)                                                           S nlink_t                     link counts for directory entries (Section 4.14) off_t                       file sizes and offsets (signed) (seek, Section 3.6)                                                              l pid_t                       process IDs and process group IDs (signed) ( ections 8.2 and 9.4)                                                                              S ptrdiff_t                   result of subtracting two pointers (signed) rlim_t                      resource limits (Section 7.11) sig_atomic_t                data type that can be accessed atomically ( ection 10.15)                                                                           S sigset_t                    signal set (Section 10.11) size_t                      sizes of objects (such as strings) (unsigned) ( ection 3.7)                                                                             S ssize_t                     functions that return a count of bytes (signed) (ead, write, Section 3.7)                                                                               r time_t                      counter of seconds of calendar time (Section 1.10) uid_t                       numeric user IDs wchar_t                   can represent all distinct character codes 10 Conflicts Between Standards     ISO C defines the function clock to return the amount of CPU time used by a process. The value returned is a value. To convert this value to seconds, we divide it by CLOCKS_PER_SEC, which is defined in the<time.h> header. POSIX.1 defines clock_t the function times that returns both the CPU time (for the caller and all its terminated children) and the clock time. All these time values are clock_t values. The sysconf function is used to obtain the number of clock ticks per second for use with the return values from the  times function. What we have is the same term, clock ticks per second, defined differently by ISO C and POSIX.1. Both standards also use the same data type (clock_t ) to hold these different values. The difference can be seen in Solaris, whereclock returns microseconds (hence CLOCKS_PER_SEC is 1 million), whereassysyconf returns the value 100 for clock ticks per second.     Another area of potential conflict is when the ISO C standard specifies a function, but doesn't specify it as strongly as POSIX.1 does. This is the case for functions that require a different implementation in a POSIX environment (with multiple processes) than in an ISO C environment (where very little can be assumed about the host operating system). Nevertheless, many POSIX-compliant systems implement the ISO C function, for compatibility. The signal function is an example. If we unknowingly use thesignal function provided by Solaris (hoping to write portable code that can be run in ISO C environments and under older UNIX systems), it'll provide semantics different from the POSIX.1 sigaction function. 11 Most file I/O on a UNIX system can be performed using only five functions: open, read, write, lseek, and close.They're are often referred to as unbuffered I/O, in contrast to the standard I/O routines. The term unbuffered means that each read or write invokes a system call in the kernel. These unbuffered I/O functions are not part of ISO C, but are part of POSIX.1 and the Single UNIX Specification. 12 File Descriptors

    To the kernel, all open files are referred to by file descriptors. A file descriptor is a non-negative integer. When we open an existing file or create a new file, the kernel returns a file descriptor to the process. When we want to read or write a file, we identify the file with the file descriptor that was returned by open or creat as an argument to either read or write.

    By convention, UNIX System shells associate file descriptor 0 with the standard input of a process, file descriptor 1 with the standard output, and file descriptor 2 with the standard error. This convention is used by the shells and many applications; it is not a feature of the UNIX kernel.

   The magic numbers 0, 1, and 2 should be replaced in POSIX-compliant applications with the symbolic constants STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO. These constants are defined in the <unistd.h> header.

 

13

    (1) open Function

      A file is opened or created by calling the open function.

 

[View full width]

#include <fcntl.h>

int open(const char *pathname, int oflag, ... /*

 mode_t mode   */ );

 

Returns: file descriptor if OK, 1 on error

    (2) creat Function

    A new file can also be created by calling the creat function.

 

#include <fcntl.h>

int creat(const char *pathname, mode_t mode);

 

Returns: file descriptor opened for write-only if OK, 1 on error

 

    Note that this function is equivalent to

    open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

    (3) close Function

    An open file is closed by calling the close function.

 

#include <unistd.h>

int close(int filedes);

 

Returns: 0 if OK, 1 on error

        (4) lseek Function

 

#include <unistd.h>

off_t lseek(int filedes, off_t offset, int whence);

 

Returns: new file offset if OK, 1 on error

    (5) read Function

    Data is read from an open file with the read function.

 

#include <unistd.h>

ssize_t read(int filedes, void *buf, size_t nbytes);

 

Returns: number of bytes read, 0 if end of file, 1 on error

    (6) write Function

    Data is written to an open file with the write function.

 

[View full width]

#include <unistd.h>

ssize_t write(int filedes, const void *buf, size_t

 nbytes);

 

Returns: number of bytes written if OK, 1 on error

《Advanced Programming in the UNIX Environment》读书笔记(1)

1、系统口令文件通常为/etc/passwd。口令文件中的登录项由7个以冒号分隔的字段组成:登录名、加密口令、数字用户ID、数字组 ID、注释字段、起始目录以及shell程序。

2、不能出现在文件名中的字符只有两个:/和空操作符(null)。

    当创建一个新目录时,自动创建了两个文件名:.和..。.引用当前目录,..引用父目录。

     A process can change its working directory with the chdir function.

3、ls(1)用以引用UNIX手册集中的一个特定项,它引用第一部分中的ls项。各部分通常用数字1~8表示,在每个部分中的各项则按字母顺序排列。

4、UNIX目录操作函数:opendir, readdir, closedir。
    三个用于进程控制的主要函数:fork, exec, waitpid。
5、头文件<unistd.h>中包含了许多UNIX系统服务的函数原型,函数原型是ANSI C标准的组成部分。
6、当度量一个进程的执行时间时,UNIX系统使用三个进程时间值:

  • 时钟时间
  • 用户CPU时间
  • 系统CPU时间 

    时钟时间又称为墙上时钟时间(wall clock time),是进程运行的时间总量,其值与系统中同时运行的进程数有关。
    用户CPU时间是执行用户指令所用的时间量。
    系统CPU时间是为该进程执行内核所经历的时间。
    用户CPU时间 和 系统CPU时间的被称为CPU时间。
    要取得任一进程的时钟时间、用户时间和系统时间很简单,只需执行命令time(1), 其参数是要度量其执行时间的命令。如:
[bonn@localhost unix_advance]$ time ps
  PID TTY          TIME CMD
 3734 pts/2    00:00:00 bash
 6743 pts/2    00:00:00 ps

real    0m0.023s
user    0m0.010s
sys    0m0.013s

7、BSD: the Berkeley Software Distribution

开源授权协议

[说明]:本文摘自《程序员》2008年06月刊许洪波教授的《开源授权协议(License)初探》一文,版权归原作者所有。


1OSI(www.opensource.org)是目前世界上针对开源软件授权进行认证的唯一机构。

2、开源软件的特点:

  • 免费的再发布:软件授权拥有者必须允许,包括软件的获得者和使用者将软件重新分发给其他人,而不向版权的拥有者支付版权相关的费用。

  • 源代码的访问:开源授权需要提供源代码。

  • 衍生作品:授权必须允许使用者修改软件,并在其基础上做出创新工作。授权必须允许这些修改和衍生作品在和原来的软件版权条件相同下发布。

  • 杜绝歧视:只要遵守开源许可版权,人人都可以使用开源软件;同时,开源软件版权不得限制任何人在特定领域使用该软件。

3、开源授权模式:

1)强开源约束授权——GNU GPL。基于GPL的任何软件及衍生应用程序,其源代码必须公开,并不得因此收费。

2)弱开源约束授权——Mozilla公用授权(MPL)和LGPLMPL协议要求假如你修改了一个基于MPL协议的源代码,则必须列入或公开你所做的修改。假如你的软件采用了基于LGPL的开源软件,LGPL要求任何针对LGPL开源软件的修改必须公开其源代码,但不要求基于源代码之上的衍生应用开放其源代码。

3)无开源约束授权——BSD授权协议。BSD几乎允许用户做任何他们想要想要在BSD的授权代码上做的事情;他们也可以将软件用于免费或商业目的;他们也可以发布或不发布变更后的源代码。BSD的唯一要求就是软件使用者声明他们使用了软件原作者的著作权。

(4)其他开源授权。

硬盘安装Fedora 9时死机?

前天晚上在Fedora9下装完ATI显卡的驱动以后,升级系统,昨天早晨起来一看,我的本本过热休眠了(发现Fedora下经常出现这种情况,而Windows下很少出现,可见Linux的电源管理确实还有问题),当时没有管它。

昨天晚上到了半夜,决定切换到Fedora下玩一玩,结果发现进不了图形界面了,字符界面也还闪来闪去的,实在没办法,重装。非常不幸的是,重装到一半的时候,CPU过热又歇菜了。

这时重启发现只能进grub控制台,无法进Windows了。顿时傻了。

今天早晨来实验室上网搜索修复MBR的方法,最简单的就是用Windows安装盘。拿出Win2003的盘插到光驱一试,没反应,My God!光驱又坏了!!!难道我辛辛苦苦好几年积攒的文档就眼看要人间蒸发付诸东流了吗?

我不甘心,继续搜索grub的使用方法,试着敲入如下的命令:

kernel (hd0,6)/isolinux/vmlinuz <br  />initrd (hd0,6)/isolinux/initrd.img <br  />boot

成功了,终于可以进入继续安装Fedora 9的界面了!
只要能够进入一个操作系统就好说了,不管它是Windows还是Linux!

EMC-CBR故障诊断研究(四)

1、系统组成
   本系统是由
CBRRBR组成的混合系统。系统结构如下图所示。系统的核心是推理机,推理机根据用户输入的故障描述,既可以将故障描述转化为新的案例,从而进行对案例库进行操作;又可以将故障描述转化为事实,对规则库进行操作。但CBRRBR的地位并不是等同的,CBR起主导作用,RBRCBR起监督作用,二者的推理结果由综合机制进行综合。本系统采用友好的人机界面,普通用户输入故障描述后,系统经推理后给出诊断建议,并对给出的建议进行解释。另外,为了便于对系统知识(案例库、知识库和事实库)进行管理,系统可以由知识工程师进行修改。

2、案例表示与存储

参见博文“EMC-CBR故障诊断研究(一、二)”

3、案例检索

参见博文“EMC-CBR故障诊断研究(三)”

4、案例重用

案例重用的主要任务是对检索到的案例的结论进行修正。基本思想就是将案例库中与目标案例最相似的案例的结论与次相似的案例的结论进行对比,如果二者仅仅是谓词函数的参数不同,可以认定无需对最佳匹配案例进行修改;如果二者不仅参数不同而且有谓词上的出入,则需启用基于规则的推理,最终利用CBRRBR的综合机制利用RBR的结论对最佳匹配案例的结论进行修正。

5、

案例的保存

    在案例保存时要进行模式归纳(Schema Induction)。模式归纳的含义就是指:如果类比导致了一个解,则执行两类似体的泛化过程,以便形成一个抽象的案例模式。简而言之,就是寻找两类似体的共性,然后加以抽象和泛化。

案例保存的过程可以看作一个归纳学习的过程,很多归纳学习的方法都可以应用于案例保存,如产生预测试方法(INDUCE1.2)。

6、案例的维护

心理学家在研究记忆机理时,提出了著名的遗忘曲线理论,即长期不用的信息将会被逐渐遗忘。在基于案例推理中,案例库的维护很重要,必须将长期不用的案例删除,因为这种案例很可能是噪声案例,例如误诊的病例、误判的案件等。Aha建议对案例库中的每个案例建立一个匹配记录,就可以删除那些噪声或无用的案例,以维护案例库的有效性。Aha提出案例求精算法IB3,表述如下[51]

输入:案例库S和测试案例集T

输出:精化案例库S’

过程:

(1)    从测试案例集T中任选一个测试案例t

(2)    设法从案例库S中找到一个案例s,它与t有最佳匹配,其相似度超过某个阈值;

(3)    如果找不到这样的s,则转到(8);

(4)    若确认ts属于同一类,则转(9);否则把t加上它所属的类c的标志后存入库S

(5)    从库S中找出所有这样的案例si,它们和t的相似程度至多不大于st的相似程度,所有这些si的匹配记录要扣分;

(6)    从库S中删除记录分数小于某个规定值的所有案例;

(7)    如果测试集的案例已经用完,则算法结束,否则转(1);

(8)    从库S中任选一个案例s,转到(4);

(9)    从库S中找出所有这样的案例si,它们和t的相似程度至少不亚于st的相似程度;

(10)转到(7)。

       7、

基于规则的推理

基于规则推理(RBR)子系统是一个简化的专家系统。RBR子系统由事实库和规则库组成,规则库中存放由专家经验中提取出来的专家规则,以产生式表示;事实库是由推理机通过人机界面从用户的输入中提取出来的事实,以命题逻辑表示。

例如,和上面讨论的case6相关的规则有“使用导电橡胶、衬垫之类的屏蔽材料时,不但要保证接触面上的良好的导电性(接触面去除所有漆),而且还要保证一定的压缩量。”,可以用产生式规则表述如下:

Shielding(product, conductive_tape) Shielding(product, condutive_gasket) => Wipe_off(interface, lacquer) (Compress(conductive_tape) Compress(conductive_ gasket))

   RBR的推理采用不确定性推理。不确定推理包括前提条件的不确定性、结论的不确定性以及推理过程的不确定性。根据电磁兼容知识的特点,必须综合利用这三种不确定性才能比较确切的模拟电磁兼容专家的推理过程。不确定推理的通用表示方法为[20]

                            IF [(p1, f1, t1) AND (p2, f2, t2) ANDAND (pm, fm, tm)]

                            THEN [((q1, g1, s1), (q2, g2, s2)…)] WITH CF(R)

其中,pi表示模糊前提条件,qi表示模糊结论及动作,CF(R)为可信度,fi是表达前件的可能性分布,ti是前件的确信程度,gi是表达结论的可能性分布,s1是结论的确信程度。

    对于前件,可以采用表达方案:,p为模糊命题,x为对象名,Ax的属性名,D是确定性状态表达,p的相应的确定性命题,是命题的不确定性度量。

例如,某模糊命题为:

如果为感应耦合(可信度0.9),且电路频率很高(模糊数0.8),则耦合为容性耦合(可信度0.7)

则该命题可以表述为:

                          IF [(p1,0.9) AND (p2,0.8)] THEN[(q1, 0.7)] WITH CF(R)

其中,

R为根据不确定推理理论计算出的整个命题的可信度。

     8、

CBRRBR的综合机制       

   当目标案例和CBR案例库中的源案例的相似度低于阈值时,启用RBR。如果利用RBR能够推导出结果,则将RBR的结论作为最终诊断结果,将CBR的结论作为建议一同提交给用户;如果由于规则的不完整RBR无法推导出结论,则将CBR的结论作为诊断结果提交给用户,但此时必须注明该结论的可信度(可信度可以用目标案例和源案例的相似度表示)。