/首页
/开源
/关于
困难人生之CLang的fork
发表@2018-11-20 23:11:03
更新@2023-01-21 22:47:40
我一直苦苦思索如何才能更好地更快地利用CLang做些什么 , 首先说是这门语言按照年龄算应该是个老家伙了 , 算是大爷级别的 , 但是这么多年过来了 , TIOBE依然排行第二 : ![](https://ti-node.com/static/upload/6470646087261618176) 这就说明了一个问题 : ![](https://ti-node.com/static/upload/6470647362166456320) <九阳神功>是武林中至阳的一门内功学法 , 当时张无忌在那破山沟子里没事儿干 , 就天天对着这玩意练 , 虽然练习的时候不知道这玩意到底有啥用也看不出来这玩意有啥用 , 但是后来他练什么都快的很 , 俗称写轮眼 , 瞪谁谁怀孕 ... 搞CLang就和搞<九阳神功>差不多 , 搞来搞去地不知道自己搞什么 , 也不知道有什么用 , 而且也搞不出东西来( 这才是关键 ) , 所以我就一直琢磨能不能出点儿东西给有志于学习CLang的有志青年 . 这个世间 , 一切皆为CURD , 唯有CURD才是毕生追求 , 花式CURD乃人生之辉煌 ! 所以 , 老李要手把手来教你如何使用CLang CURD ! 我们的整体思路就是利用CLang搞一个HTTP服务器 , 然后你就通过CURL提交数据实现花式CURD . 在此之前 , 我还是希望大家有 : - 一定的编程基础 , 能分清if else , 知道什么是for和while - 至少看过一遍那些个CLang的课本 , 书名不定 , 啥都行 - 准备好ubuntu LINUX , 用Windows的大爷一律不伺候 , 用Mac的如果出现编译不过也一律不管( 因为我也不懂 ) ### 反正 , 我也不太懂CLang , 如果你被我带翻车了 , 那也别怪我 , 是你自己要上车的 ... ... ![](https://ti-node.com/static/upload/2-1F61G2163cD.gif) 今天就先简单点儿 , 我们先尝试搞一搞多进程 , 毕竟多一个进程多一份力量 . 在Linux下 , 创建一个进程的API叫做fork , 这个单词翻译过来有"分叉"的意思 , 这里需要注意的一点是fork不是CLang的功能 , 而是系统提供的 . 在当前执行进程中调用fork就会产生一个子进程 , 当前进程称为子进程的娘进程( PS : 是这样的 , 一姐看到了我这篇文章 , 说什么父进程的叫法是典型的男权主义 , 而且男的又不会生孩子 , 考虑到她说的在理 , 再加上我又打不过她 , 于是就改称叫娘进程得了 , 你们面试时候别搞错了 ) , 娘进程和子进程其实就是平行世界 , 你不鸟我 , 我也不鸟你 . 那么 , 过多高深的理论我是讲不下去了 , 反正你们也听不懂而且也不想听 , 所以就先来点儿实在的 : ``` // stdio.h是标准输入输出库 , 没这玩意就不能CURD , 不能CURD人生还有什么意义? #include
// 反正就是定义一大坨衍生数据类型 , 不懂就先记住 #include
// unix standard , 翻译过来大概就是unix标准的意思 , 这个头文件里有很多函数 , 比如大名鼎鼎的sleep , 当然了还有fork #include
// *nix标准库 , 具体怎么回事不知道 , 但我告诉你牛逼哄哄的exit函数就在这个文件里 ... #include
// 任何一个CLang程序都会先从main函数开始 , 就像PHP Web框架单一入口的index.php一样 int main( void ) { // pid_t其实就是int类型 , 为了更好的移植性 , *NIX就利用int衍生出了这么个新类型 , 记住了这玩意是专门用来表示进程ID的数据类型 ! pid_t pid; // fork系统调用是个比较奇葩的玩意 , 一般说来函数只能return一次 , 但这货调用完毕后返回两次 , 一次是娘进程的 , 一次是子进程的 . pid = fork(); if ( pid < -1 ) { printf( "fork error.\n" ); exit( -1 ); } // 当返回pid为0的时候 , 表示这是在子进程中 else if ( 0 == pid ) { printf( "我是子进程 , 我的进程ID是%d , 我的父进程ID是%d\n", getpid(), getppid() ); } // 当返回pid大于0的时候 , 表示这是父进程中 , 返回的这个pid就是子进程的PID进程号 else if ( pid > 0 ) { printf( "我是娘进程 , 我的进程ID是%d , 我子进程ID是%d\n", getpid(), pid ); } return 0; } ``` 激动人心的时刻来了 , 将上面的代码复制粘贴( 应该一定是复制粘贴吧 ? 没几个人会真正亲自敲吧 ... )走保存成fork.c , 然后连续输入如下两个命令 : ``` // 这行命令就是传说中编译 , gcc就是传说中的编译器 gcc fork.c // 上面gcc秉承的一贯宗旨就是*NIX中著名的 " 没有消息就是好消息 "原则 , 就是说如果编程成功了 , 就没有任何提示 , 如果有毛病了 , 他就有消息吐到屏幕上 . 然后就会在根目录下产生一个 a.out 可执行文件 ``` ![](https://ti-node.com/static/upload/6470661208646090753) 这里有个问题就是"为毛fork返回的时候娘进程得到的pid就是大于0 , 而子进程则是0" , 其实原因也没啥的 , 就是 " 因为子进程中可以通过getppid()来获取娘进程的PID , 但娘进程并不能通过某个函数或调用来获取子进程的PID , 因为一个娘进程可能会有很多个子进程 " . 前面我们说了 , 娘进程和子进程其实就是平行世界 , 下面我们操作一波儿来验证一下 , 那么如何才能拯救平行世界呢 ? 唯有老王 ! 只有老王的smartmesh可以拯救平行空间 , 拯救宇宙 ! ``` #include
#include
#include
#include
int main( void ) { pid_t pid; int counter = 0; pid = fork(); // 总有泥腿子不明白下面这种写法 , 妈的 , 你知道当初有多少泥腿子在写php的时候手残判断相等直接写成 $counter = 1 么 ? 你知道 if ( $counter = 1 ) { // 删库跑路 }永远一定会执行么 ? 但你反着写试试 , 要是能运行我直播裸奔 : if ( 1 = $counter ) { // 删库跑路 } if ( 0 == pid ) { counter += 100; printf( "counter = %d\n", counter ); } else if ( pid > 0 ) { counter += 200; printf( "counter = %d\n", counter ); } return 0; } ``` 好了 , 这坨代码复制粘贴走 , 编译一下 , 运行一下 , 看看结果 , 自己感受一下 . 今儿先到这里 , 明天接着说 , 可能会说些关于僵尸进程之类的东西 ...