第二题:
-module(for).
-export([for/3,empty_proc/0,post_msg/1]).
for(N,N,F)->[F()];
for(I,N,F)->[F() | for(I+1,N,F)].
empty_fun()->
receive
_Any->
io:format("~w is exit",[self()])
end.
post_msg([]) -> void;
post_msg([Head | Tail])-> Head ! "Other",
post_msg(Tail).
在shell里面输入
CreateProc=fun()->spawn(fun for:empty_proc/0) end. %创建进程的函数
PidList=for:for(1,10,CreateProc). %创建10个进程
for:post_msg(PidList). 发送消息给进程
这几天写erlang的感觉已经来了^-^
前几天写了个小工具,因为在安装的时候需要一天安装玩几十台机器,因此为了方便需要写个程序可以同时直接生成配置文件,省得到时候要一台一台地配置,
时间比较紧迫,临时学习了下XML,写得很仓促,半天学XML和wxwidget操作XML,不得说XML确实很麻烦,不知道当初配置文件为什么选用XML,后来据说是因为写这个的程序员喜欢新技术....
因为在写XML的时候需要一个个保存每个节点要创造什么,每个key对应一个val,刚开始用一个结构体,里面保存了这个节点的name,val,func,就是没有保存key,其实结构体里面把函数换成key会更好,因为我最后看了下代码,其实所有的操作就key和val不同,所以写一个函数CreateNode函数来创建节点,写的时候是想到这点了,但是不知道为什么要把key换成一个函数,然后函数里面保存这个key,这样每次增加东西就要增加一个函数,感觉这个设计很白痴,更糟糕的是用的是数组,也就是增加函数的同时还要更改数组
总结了下,这次写代码得到几点经验:
1:不要把一个东西写死在函数里面,可以利用C++的默认参数,比如我在一个函数里面有个int类型,现在你感觉他是固定的,但是以后说不定什么时候就会改变,或者说每个函数调用都可能需要不同的数字,这个时候利用C++的默认参数,不会增加程序员的负担,以后如果发现这个数字不固定了,不用更改函数声明
2.这次写创造一个节点的时候,也就key的这个数组不变,比如createA和CreateB也就里面的key array不同,我原来是这样的CreateA(val_array),CreateB(val_array),然后函数再生命key array,但是其实可以把key array函数参数里面,结果可以省去写很多createX的函数
3.做第二点的时候想把key array利用可变参数放进去,但是发现不会用,后来发现如果有可变参数还是很方便,因为在创建wxarrayString的需要每次都array.add(str),很不方便,如果有可变参数就方便多了,这个还是要学下
int main(void) { BOOL fOk = FALSE; HANDLE hFileSrc = CreateFile(_T("test.txt"),GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); HANDLE hFileDest = CreateFile(_T("cpy_test.txt"),GENERIC_WRITE,0,NULL,CREATE_ALWAYS, FILE_FLAG_OVERLAPPED,NULL); if (hFileSrc == INVALID_HANDLE_VALUE || hFileDest == INVALID_HANDLE_VALUE) { cout<<GetLastError()<<endl; system("pause"); return 1; } BOOL ret = FALSE; char str[1024] = {0}; DWORD dwNumberRead = 0; OVERLAPPED ov = {0}; ov.hEvent = NULL; ov.Offset = 0; ov.OffsetHigh = 0; while (true) { ret = ReadFile(hFileSrc,str,1023,&dwNumberRead,&ov); if (ret == FALSE) { if (GetLastError() == ERROR_IO_PENDING) { GetOverlappedResult(hFileSrc,&ov,&dwNumberRead,true); } else { cout<<GetLastError()<<endl; break; } } if (ov.InternalHigh == 0) { break; } str[ov.InternalHigh] = 0; cout<<str<<endl; ov.Offset += ov.InternalHigh; memset(str,0,sizeof(str)); } }
代码基本都是在读取的时候立即返回,而不是类似阻塞IO那样,一直到读完才返回,基本原理也就是把这个把IO放进队列里面,如果请求只是放进队列里面而没有处理,getlasterror返回的是ERROR_IP_PENDING,这个时候GetOverlappedResult是等待读完再继续,也可以WaitSingleObejct要读取的文件或者overlapped里面的hevent来等待读完..
刚写完这段代码就有点奇怪,既然要等待他读完才能继续执行,为什么还要用异步,用同步不也可以??后来想了下,这样做的好处就是可以让原本等待在IO操作完成的时间中做其他事情,然后到一定的地方在等待完成,如果使用非阻塞IO,在IO操作完成操作后需要调用一段函数,而这段函数又与IO操作无关,这样无缘无故浪费了中间一段时间,还不如在IO操作前做些其他的事情....最近工作用到的读串口也是这样,虽然也是在调用ReadFile后立即等待操作完成,但是如果哪天需要在中间加入 一些操作,那修改起来就很麻烦...
还有一个比较2B的时候,我在调用CreateFile的时候使用了FILE_FLAG_NO_BUFFERING这个标志,结果读的时候总是错误,说是无效参数,后来发现是在CreateFile的时候指定了FILE_FLAG_NO_BUFFERING
MSDN是这样说的:
The file or device is being opened with no system caching for data reads and writes. This flag does not affect hard disk caching or memory mapped files.
There are strict requirements for successfully working with files opened with CreateFile using the FILE_FLAG_NO_BUFFERING flag, for details see File Buffering.
windows核心编程里面则说指定了这个标志后读写必须使用64的倍数....
需要注意的是,传入的是overlapped的地址,所以在overpaeed作用域过后,如果IO操作还没完成,则会发生未知错误
如下代码
void ReadData(HANDLE hFile) { OVERLAPPED ov = {0}; ov.hEvent = NULL; BYTE b[100]; ReadFile(hFile,b,100,&ov); }
1 #define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER )
宏功能:获得一个结构体变量成员在此结构体中的偏移量。
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址,即相对于0的偏移量,要的就这个;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型,size_t应该最终为unsigned int类型。
此宏的巧妙之处在于将 0 转换成(TYPE*),这样结构体中成员的地址即为在此结构体中的偏移量。
示例:
#include <stdio.h>
#define offsetof(TYPE, MEMBER) ((int)(&((TYPE *)0)->MEMBER))
struct _test_
{
int x;
int y;
float z;
};
int main(void)
{
int temp = -1;
temp = offsetof(struct _test_, z);
printf("temp = %d\n", temp);
return 0;
}
运行后结构为:temp = 8。
显然求出了 结构体成员变量 z 在结构体中的偏移量为 8。
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
宏功能:从结构体(type)某成员变量(member)指针(ptr)来求出该结构体(type)的首指针。
#include <stdio.h>
#define offsetof(TYPE, MEMBER) ((int)(&((TYPE *)0)->MEMBER))
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
struct _test_
{
int x;
int y;
int z;
};
void Assignment(struct _test_ *t)
{
t->x = 1;
t->y = 2;
t->z = 3;
}
void GetheadPoint(int *tz)
{
struct _test_ *p;
int temp = -1;
p = container_of(tz,struct _test_, z); //根据成员变量的地址获得该结构体的首地址
temp = p->y; //根据首地址获得其中另外一个成员变量的值
printf("line31 = %d\n", temp);
}
int main(void)
{
int temp = -1;
struct _test_ tmp; //定义一个结构体变量
Assignment(&tmp); //给这个变量赋值
GetheadPoint(&tmp.z); //只传给这个函数一个结构体成员变量的地址
printf("line43 tmp - >x = %d\n", tmp.x);
return 0;
}
运行结果为:
line31 = 2
line43 tmp - >x = 1
大概解释一下:先定义一个结构体并给其赋值,现在 GetheadPoint函数只传入这个结构体的一个子成员变量地址。在 GetheadPoint函数中通过container_of宏来获得此结构体的首指针,通过此首指针即可以获得此结构体的其它子成员的值。
1、.typeof( ( (type *)0)->member )为取出member成员的变量类型。
2、定义__mptr指针ptr为指向该成员变量的指针
3、mptr为member数据类型的常量指针,其指向ptr所指向的变量处
4、.(char *)__mptr转换为字节型指针。(char *)__mptr - offsetof(type,member))用来求出结构体起始地址(为char *型指针),然后(type *)( (char *)__mptr -offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针。
5、.({ })这个扩展返回程序块中最后一个表达式的值。
这段时间因为项目需要,学了下window编程的录音和播放,以前没接触过这方面,网上资料也少,只能自己慢慢鼓捣了,鼓捣了5天才写出来,还有界面要用flex,以前也没接触过这方面,也自己慢慢鼓捣,不过还算快,3天基本可以学会,网络编程也学了广播,昨天开始搞组播,但是要装linux虚拟机,虚拟机速度慢,现在还在更新,昨天下午到今天早上还都不能上网,怨念啊
还学了汇编,虽然之前这些就知道得差不多了,但是没有实践的话还是不心安,还是拿起<<intel汇编语言程序设计>>来看,本来学了汇编后想学反汇编或者说写操作系统,但是看了下发现还是放下吧,方向改为网络,打算今年把TCP/IP协议这方面看完,书是<<TCP/IP详解>>
这个月内要把线性代数学完,准备自考了,英语也要在八月份学完,高数也是
或许以后可能会自考,需要考线性代数,最近在准备线性代数的东西,原本是买了<<线性代数及其应用>>的书,然后配合麻省理工大学的那个教授的视频看,网上给这两个的评价都很好,豆瓣上是给线性代数及其应用的书9.0分的评价,视频在VC和网上更是赞誉不断,但是看下去后越看越糊涂,刚开始矩阵运算方程式计算还可以,这些之前初中都有自己摸索过了,到了行列式基本算是整个人都斯巴达了,虽然不认为自己算是天才级的人物,但是起码智商也还可以,搞得自己有点失去信心,后来土豆网上找了吉林大学的远程教育视频才开始搞懂什么是行列式
想想不是第一次这样了,记得之前学C,windows,数据结构都是这样,受网上影响太大,总喜欢找外国书的来看,但是后来基本都是通过国内的书学会的,最近公开课蛮火的,VC上的评价也是一篇好,但是我看了JAVA编程的,还有那个python,以及线性代数,发现这种东西更适合有基础或者说复习的人去看,否则到头来只是一头雾水....甚至我觉得没什么必要看了,大概很多人只是抱着炫耀的态度去看,反正我觉得没什么用
网上好像对于外国的书不管你看得会看不会都是叫好的,所以导致误导的人也不少,如算法导论,被誉为算法圣经,但是我总觉得这本书当提纲或者教学书看看还可以,当自学的估计没几个人看得懂,我一只认为这本书属于看的不会会的不看,当然也有可能需要复习的,我早期学算法也是用算法导论,后来看不懂,是自己网上找的还有自己刷OJ,ACM然后找答案自己一行一行代码调试下去,后来才开始偶尔翻翻算法导论,所以我并不推荐这本书当学算法的书,数据结构,严蔚敏的伪码不喜欢,所以没学过他那本书,后来网上推荐一本叫<<数据结构与算法分析>>,这本书我第一次看也是头晕晕,不知道他在讲什么,后来看的是铁道出版社的一本数据结构,虽然这本书图论因为编译器的原因他那里面的例子都不适合我用的编译器(我用GCC,他用TC),但是自己修改下还是可以,再后来是看<<数据结构,应用C++标准模板库>>,前一本书已经绝版,第二步本书估计很少人听过
深入理解计算机系统,我倒觉得还不如去学汇编,然后学下系统编程,看完这本书基本够学完这两样了
这段时间买了1000+的书吸收了一些教训后才开始趋于理性,吃点亏才长记性啊
当然还有一点可能是我已经适应国内应试教育了
deb ftp://ubuntu.realss.cn/ubuntu/ lucid main restricted universe multiverse deb ftp://ubuntu.realss.cn/ubuntu/ lucid-backports restricted universe multiverse deb ftp://ubuntu.realss.cn/ubuntu/ lucid-proposed main restricted universe multiverse deb ftp://ubuntu.realss.cn/ubuntu/ lucid-security main restricted universe multiverse deb ftp://ubuntu.realss.cn/ubuntu/ lucid-updates main restricted universe multiverse deb-src ftp://ubuntu.realss.cn/ubuntu/ lucid main restricted universe multiverse deb-src ftp://ubuntu.realss.cn/ubuntu/ lucid-backports main restricted universe multiverse deb-src ftp://ubuntu.realss.cn/ubuntu/ lucid-proposed main restricted universe multiverse deb-src ftp://ubuntu.realss.cn/ubuntu/ lucid-security main restricted universe multiverse deb-src ftp://ubuntu.realss.cn/ubuntu/ lucid-updates main restricted universe multiversedeb http://ubuntu.uestc.edu.cn/ubuntu/ lucid main multiverse restricted universe deb http://ubuntu.uestc.edu.cn/ubuntu/ lucid-backports main multiverse restricted universe deb http://ubuntu.uestc.edu.cn/ubuntu/ lucid-proposed main multiverse restricted universe deb http://ubuntu.uestc.edu.cn/ubuntu/ lucid-security main multiverse restricted universe deb http://ubuntu.uestc.edu.cn/ubuntu/ lucid-updates main multiverse restricted universe deb-src http://ubuntu.uestc.edu.cn/ubuntu/ lucid main multiverse restricted universe deb-src http://ubuntu.uestc.edu.cn/ubuntu/ lucid-backports main multiverse restricted universe deb-src http://ubuntu.uestc.edu.cn/ubuntu/ lucid-proposed main multiverse restricted universe deb-src http://ubuntu.uestc.edu.cn/ubuntu/ lucid-security main multiverse restricted universe deb-src http://ubuntu.uestc.edu.cn/ubuntu/ lucid-updates main multiverse restricted universe deb http://ubuntu.dormforce.net/ubuntu/ lucid main multiverse restricted universe deb http://ubuntu.dormforce.net/ubuntu/ lucid-backports main multiverse restricted universe deb http://ubuntu.dormforce.net/ubuntu/ lucid-proposed main multiverse restricted universe deb http://ubuntu.dormforce.net/ubuntu/ lucid-security main multiverse restricted universe deb http://ubuntu.dormforce.net/ubuntu/ lucid-updates main multiverse restricted universe deb-src http://ubuntu.dormforce.net/ubuntu/ lucid main multiverse restricted universe deb-src http://ubuntu.dormforce.net/ubuntu/ lucid-backports main multiverse restricted universe deb-src http://ubuntu.dormforce.net/ubuntu/ lucid-proposed main multiverse restricted universe deb-src http://ubuntu.dormforce.net/ubuntu/ lucid-security main multiverse restricted universe deb-src http://ubuntu.dormforce.net/ubuntu/ lucid-updates main multiverse restricted universe
