1.背景
在把一些项目移到新的环境Centos8下gcc 8.3,使用了google 的pb库,然后在链接时发现链接错误,google::protobuf::MessageLite::SerializeToString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
2.产生错误的原因
由于protobuf库应该是在gcc 5.3以下的编译器中进行编译的,因为gcc5.3以上 主要是为了支持新的C++标准中要禁止std::string
的Copy-On-Write行为和支持std::list中size()的时间复杂度为O(1)。
2.1 Copy-On_Write(写时复制技术):
Linux在使用fork()函数进程创建时,传统fork()的做法是系统把所有的资源复制给新创建的进程,这种方式不仅单一,而且效率低下。因为所拷贝的数据或别的资源可能是可以共享的。现在Linux的fork()使用写时拷贝页来实现新进程的创建,它是一种可推迟甚至避免数据拷贝的技术,刚开始时内核并不会复制整个地址空间,而是让父子进程共享地址空间,只有在写时才复制地址空间,使得父子进程都拥有独立的地址空间,即资源的复制是在只有需要写入时才会发生,因此而称之为Copy on Write(COW)。在此之前都是以读的方式去和父进程共享资源,这样,在页根本不会被写入的场景下,fork()立即执行exec(),无需对地址空间进行复制,fork()的实际开销就是复制父进程的一个页表和为子进程创建一个进程描述符,也就是说只有当进程空间中各段的内存内容发生变化时,父进程才将其内容复制一份传给子进程,大大提高了效率。
2.2 Copy-On-Write技术的优缺点
1.COW技术科减少分配和复制大量资源时带来的瞬间延时,但实际上是将这种延时附加到了后续的操作之中。
2.COW技术科减少不必要的资源分配。比如fork进程时,并不是所有的页面都需要复制,父进程的代码段和只读数据段都不被允许修改,所以无需复制。
3.解决方法
编译时加上参数-D_GLIBCXX_USE_CXX11_ABI=0 强迫使用旧版的libstdc++.so