在某度上搜索libco全都是源碼分析,像我這樣的菜雞使用Makefile時還是有點小挫折的,下面我們一起體驗一下書寫編譯第一個ibco程序。
下載源代碼
github:https://github.com/WbtLm/libco
打開上述網址,點擊如下圖所示的綠色按鈕,選擇Download Zip:
將zip解壓,(我將裏面所有文件都拷貝到了/home/用戶名/libco/文件夾下)
書寫代碼
我們書寫第一個libco的源代碼“new.cpp”:
我是參考example_echosvr.cpp書寫的。頭文件直接拷貝就好。
#include "co_routine.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include <stack>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef __FreeBSD__
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>
#endif
#include<iostream>
using namespace std;
static void* A(void *arg) {
printf("1 ");
co_yield_ct(); // 切出到主協程
printf("2 ");
}
static void* B(void *arg) {
using namespace std;
printf("x ");
co_yield_ct(); // 切出到主協程
printf("y ");
}
struct task_t
{
stCoRoutine_t *co;
int fd;
};
typedef struct task_t task_t;
int main(void) {
stCoRoutine_t *coa,*cob;
task_t *taska=(task_t*)calloc(1,sizeof(task_t));
task_t *taskb=(task_t*)calloc(1,sizeof(task_t));
taska->fd=-1;
taskb->fd=-1;
co_create(&(taska->co),NULL,A,taska);
co_create(&(taskb->co),NULL,B,taskb);
co_resume(taska->co);
co_resume(taskb->co);
co_resume(taska->co);
co_resume(taskb->co);
printf("\n");
}
配置Makefile
初始Makefile文件是沒有我們當前的源文件“new.cpp”的命令的。我們將new.cpp放入libco根目錄下,新建一個終端,使用vim打開Makefile文件
vim Makefile
找到PROGS的定義:
這一行第一個colib是必須的(別問我爲什麼),然後後面是代碼自帶的example,的可以刪掉或者用#註釋掉。然後把new寫到一行的後面。效果如圖
然後往下翻,找到這麼一串代碼:
這些是自帶的example們,可以刪掉或註釋掉。
後面加上兩行:
new:new.o
$(BUILDEXE) #注意,這一行第一個字符必須是<tab>鍵
#此處加一個回車
效果是這樣的:
改完後保存退出。vim下按ESC鍵,然後輸入英文冒號:wq回車
編譯運行
第一次編譯只需要輸入make即可。然後我們就能看到一些提示信息
有warning可以忽略,只要沒有error就好。
然後輸入./new就可以運行:
效果跟預期相同。我們用協程完成了不同函數輪轉運行。
注意
我們第二次make時會產生亂碼各種錯誤,這是爲什麼呢?
我們在Makefile裏面寫的new文件會先編譯new(可執行文件),如果new不存在的話尋找並編譯new.cpp文件。我們在make之前要先把之前的new(可執行文件)刪除掉才行(好吧,蒟蒻不知道怎麼更優美地解決這個問題)。
第二次編譯運行:
rm new
make
./new
我們接下來就可以愉快地使用libco寫代碼了。