Stackless coroutine
1 |
|
1 | #include <iostream> |
有些時候,我們不想要有libstdc++.so的相依性,而只要依賴libc,如果要整個重寫原先的C++ Code花費太大。
1 | #include <iostream> |
看一下相依性
1 | $ g++ test.cpp -o test |
但是如果我們這樣坐的話,一切就會不同
1 | $ g++ test.cpp -o test -static-libstdc++ -static-libgcc |
這邊有三個選項
– -static-libstdc++
連結libstdc++.a
– -static-libgcc
連結libgcc.a,如果只有-static-libgcc
而沒有-static-libstdc++
不起作用,但是反過來不是那麼一回事。
– ‘-static’ 去存所有相依性
– How to Statically Link C and C++ Programs on Linux with gcc
以下的程式碼哪裡有問題
1 | pthread_mutex_t mutex; |
所謂的Spurious wakeup
就是被Blocking的Thread認為自己滿足條件而被喚醒,而事實上不是這麼一回事。例如
Spurious wakeups may sound strange, but on some multiprocessor systems, making condition wakeup completely predictable might substantially slow all condition variable operations.
由於有Spurious wakeup
的發生,為了程式的正確性,需要為此作處理。
看上面的
1 | if (q.empty()) |
當Spurious wakeup發生時,這個條件不一定滿足,因此要把if
改成while
,
由於condition variable的signal跟mutex的unlock是獨立事件,因此兩個的順序不重要,正確性都得以保證。不過這樣子的寫法一樣會造成Spurious wakeu
的問題
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
分析如下
真是後知後覺啊,最近才常是用這種方式。
先來用傳統的C語言分配資源寫法。
1 | typedef struct B1 { |
雖說用goto
可以簡化alloc的情況,不過要不要用goto
見仁見智。
如果是C++的話可以這樣寫
1 | struct D { |
在Constructor中可以接收Exception,保證Object要嘛無法使用,要嘛是一個完整的狀態。
這邊看到刪除的部份程式碼重複了,因此用Smart pointer可以更進一步。
1 | struct D { |
– Is it ever not safe to throw an exception in a constructor?
– C++ : handle resources if constructors may throw exceptions
有時間回頭看Java,發現以前沒注意到的Checked Exception,看了一下主流語言只有Java和Python有做。先不論使用與否正反意見,討論一下他在語言之中的定位。
看一下有Checked Exception的版本
1 | class CheckExceptionTest { |
和沒有的版本
1 | class UncheckExceptionTest { |
差異在於兩個地方
– Function Signature有加上throws BadUrlException
– Exception繼承的Base Class不同
這樣可以提醒編譯砌牆志檢查是否有無處理的情況(是否妥善處理就是另外一件事了),立意良善,不過
以上麵那個利子來說,如果認為storeDataFromUrl
不是一個處理Exception的好地方,只好修改這個Function的Signature
1 | public void storeDataFromUrl(String url) throws BadUrlException { |
throws會蔓延的,如果A->B->C->D->E
的呼叫方式。A處理異常,E有Checked Exception,那麼B,C,D,E都要修改Function Signature。
在throws Propagate過程中,如果遇到Interface的Issue情況更加惡化
1 | interface InterfaceCheck { |
由於我們修改了storeDataFromUrl
的Signature,所以Interface部份要跟著改,而所有實做此Interface的Signature都要改。
就跟滾雪球一樣,越滾越大。
如果同樣的我們想再A處理Exception,必須在原處做些簡單的處理。
1 | public void storeDataFromUrl(String url) { |
這麼麻煩,那還不直接用Unchecked Exception就好了,所以這一點爭議不少。
– Why doesn’t C# have checked exceptions?
– Does Java need Checked Exceptions?
– The Trouble with Checked Exceptions
– Checked or Unchecked Exceptions?
– Checked vs. Unchecked Exceptions: The Debate Is Not Over
– Checked Exceptions are Evil
去官網
1 | $ wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz |
1 | $ wget https://ftp.gnu.org/gnu/binutils/binutils-2.25.tar.gz |
Test
1 | $ mkdir afl_in afl_out |
在Stackoverflow 看到的,最近剛好再看Effective Modern C++,覺得有用,紀錄起來。
1 | #include <type_traits> |
最近想從IP Camera和FFMpeg搭上陷,不過IP Cam走得不是標準的v4l2這套,只好另尋他路。
看了幾篇文章,時做了之後可以用,增添了自信心。
紀錄一下整個思路。
仙分配一塊記憶體,當作IO Context的Buffer使用
1 | const int iBufSize = 32 * 1024; |
向FFMpeg要求建立AVIOContext
1 | int ReadFunc(void* ptr, uint8_t* buf, int buf_size) |
上面的ReadFunc
和SeekFunc
就代表Read和Seek的動作,而pContext
就是有關的上下文,ReadFunc
和SeekFunc
被呼叫時,pContext會被傳入ptr中。因此需要自行轉型成正確的上下文。
建立AVFormatContex
,這邊我是採用比較偷懶的作法,我已經知道InputFormat了,所以不需要Probe。如果要Probe可以參考Reference的連結。
1 | AVFormatContext* pCtx = avformat_alloc_context(); |
依照FFMpeg正常的流程使用
1 | if (avformat_open_input(&pCtx, "", 0, 0)) != 0) |
接著就跟一般無異了
使用完後需要釋放資源
1 | avformat_close_input(pCtx); // AVFormatContext is released by avformat_close_input |
又一個實驗性質的玩意,由於目前沒有IDE支持,一切從零開始。
1 | module Math; |
命名成add.ixx
接著main進來了
1 | #include <stdio.h> |
以下是編譯過程
1 | C:\> cl /c /experimental:module add.ixx |
一切都看起來很美好
如果我們新增一個sub.ixx
呢
1 | module Math; |
main也順勢改寫
1 | int main() |
這下子編譯救出錯了
1 | C:\> cl /c /experimental:module add.ixx |
這個情況看起來Math.ifc被sub.ixx複寫了,以至於add的資訊消失。雖然可以用Module subdomain斃掉,不過這樣子很難用啊。
試著在ixx當中放一些Template function,不過完全無效。還是只能放在Header file當中。
有了Module之後,除了Template這種避不開的之外,Header file的重要性可能會大大降低 (再也不用擔心Winsock.h 跟 Windows.h的恩怨情仇了)。也能加速奇編譯速度。不過還在實驗階段,靜觀其變吧。
Visual C++ 2015提供了一個Coroutine的實驗性實作,未來可能會被列入C++17當中,因此先來體驗一下
這寫法就跟Python差不多了,直接用yield
就行了
不過跟Javascript的Generator還是有一定程度的不同
1 | #include <iostream> |
以下是個示範程式
1 | #include <future> |
future<void>
和await
的語法實在是有點突兀(尤其是其他語言都用async
和await
之後)
如果我們拿掉await
會造成怎樣的結果
1 | void noncoro() { |
可以看到兩個函數的不同
calculate_the_answer
-> Child Thread Returncalculate_the_answer
-> Main Thread Return這個範例有點複雜,有時間在研究吧
1 | #include <windows.h> |
– Resumable functions in C++
– Coroutines in Visual Studio 2015 - Update 1
– Stackless coroutines with Visual Studio 2015