这两天在想,到底是否学会了,怎么验证你学会了,我一直在纠结,但是昨天早上醒来,我觉得我可能迄今为止做错了很多事,比葫芦画瓢?谁都会,靠着自己脑中残留的记忆来照着写,真的是硬实力吗?我不觉得,我认为只有自己写出来了,才算你牛逼。
这两天虽然只写了不多的代码,但我觉得让我受益匪浅。把遇到的问题即时记录下来则会很有帮助。
1.warning的警告要看在哪里警告,警告的提示跟函数参数的出入在哪,我的问题在于编译时提示我recvfrom的参数有问题,
在此项目中,创建了一个信号量集合并包含了三个信号量.
使用一个信号量 (SEM_MUTEX) 用于共享内存的互斥.
使用两个信号量(SEM_EMPTY 与 SEM_FULL)用于环形队列的同步
SEM_EMPTY = 0,表示目前队列只有0个数据为空(本人倾向于记SEM_CURRENT=0,更方便记忆。)
当 SEM_FULL = 0 时,表示目前队列剩余0为满,则生产者进程阻塞。(本人倾向于记SEM_REST=0,更方便记忆)
1 | int inet_aton(const char *cp, struct in_addr *inp); [addr to network] |
1 | char *inet_ntoa(struct in_addr in); [network to addr] |
1 | short htons(short data); [host to network short ] |
1 | int atoi(const char *nptr); |
在与文件链接形成可执行文件后,会绑定在一起,所以优点也就是在执行的时候不需要加载,可以直接运行,缺点相同的就是重复的占用会导致内存开销过大
静态库在linux以.a结尾,在windows中以.lib结尾。
首先需要把file.c编译成file.o:gcc -c file.c -o file.o
然后把.o文件生成静态库:
1 | ar -rs file.a file.o |
生成静态库之后我们需要把main.c与静态库链接起来生成可执行文件:gcc -I<头文件路径> -L<库的路径> main.c -l<静态库的名字> -o <可执行文件名>
gcc 编译器默认搜索头文件与库文件的路径
/usr/include 为头文件默认路径
/usr/lib 与 /lib 为库的默认路径.
假如你已经把头文件,库拷到了默认路径那么就不需要加上上两个参数。
动态库
与静态库相比显然有着不同的特性,动态库加载速度偏慢,但在一般情况对内存的占用要比静态库更少。
在windows中以.dll文件结尾,十分常见,在linux中以.so文件结尾.
当可执行文件调用动态库中的函数时,则需要加载动态库到内存中
动态库的制作:
gcc -c file.c -o file.o
然后生成动态库gcc -shared file.o -o file.so
链接的命令则和静态库的一样,然后我们如果只这样执行可执行文件是会报错的:
error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
这是因为我们没有将动态库加载到内存中,默认动态库的位置是/usr/lib,如果我们的动态库在当下目录,我们可以export LD_LIBRARY_PATH=.