跨平台是什么意思呢?先了解一下平台的概念以及平台的差异。我们知道一个VC编译出来的*.exe是不能在Linux运行的,不能运行的原因可以概括为以下几个方面:

1. 文件的结构与格式

可执行程序是按定义好的格式来组织的, Microsoft 他 GNU对程序文件的定义是不一样的,如GNU使用 ELF格式定义。也就是说,当操作系统(Windows/Linux)试图把一个程序文件加载到内存里准备运行的时候,它可能会发现这个文件格式不对。

2. 依赖库

程序的最基本的运行库是C runtime,比如你调用的printf就是C库的接口,这间味着你发布的程序是依赖C的动态库的, Linux上叫libc.so

3. 指令集与大小端

最常见的指令集用Intel, ARM 指令集,如果你的程序是为Intel PC编译的,那么这个程序就不可能在ARM平台上运行。(也许它们都是运行着Linux)。但是指令集都不一样的话,怎么能够运行呢?

通过上面的讨论,可以发现跨平台好像是一件不能完成的任务。那么为什么我们还能经常见到跨平台这个词呢,JAVA, ACE ,QT等等,它们都是跨平台的。那么它们是怎么跨平台的呢?

第一种跨平台的方式:JAVA

首先说JAVA。JAVA这个东西跨平台最彻底,同时也可以说它最“不跨平台”。JAVA编译出来的class文件并不能直接在目标平台上运行,它必须由一个叫java.exe /java的程序解释执行。显然,在不同的平台上这个java解释程序是完全不一样的。最基本的,windows上的解释程序叫java.exe,linux上的叫java,是完全不的两个文件。这件事说白了就是,你写一个脚本,交给2个不同的程序去运行,运行结果一致。

如果对比一下,连perl, python这种脚本语言也是跨平台的。它们和JAVA“跨”的方式本质上一样。Java跨的方式更隐蔽一些,它是先把 .java文件编译成了中间指令集.class,再解释执行这个中间指令集的。

第二种跨平台的方式: 仿QT

我就直接说我们可以怎么跨平台吧。简单地说,就是写2个平台相关的代码,屏蔽了平台差异。在业务代码里,完全不要用平台相关的代码。

以线程为例,windows/linux下实现线程的方式是完全不一样的。于是我们先定义一个线程类。

#ifndef _OSAPI_THREAD_H
#define _OSAPI_THREAD_H
/* presented by 阿发你好 */
class OS_Thread
{
public:
OS_Thread();
virtual ~OS_Thread();
// 创建并启动
virtual int Run();
// 等待和收回资源
static void Join(OS_Thread* thrd);
// Sleep函数
static void Msleep(int ms);
static void Sleep(int s);
public:
virtual int Routine() = 0;
private:
void* m_Priv;
};
#endif

也就是说,无论你是XXX平台还是YYY平台,总该是有线程支持的。所以麻烦你先按照上述接口实现一个线程类吧。我在业务代码里要使用线程的时候,就使用线程接口,完全不使用平台相关的接口了。

#include "../osapi/Thread.h"
class MyThread : public OS_Thread
{
public:
int Create()
{
m_quitflag = false;
run();
return 0;
}
void Destroy()
{
m_quitflag = true;
Join(this);
}
private:
/* 线程函数 */
virtual int Routine()
{
while(!m_quitflag)
{
printf("helloafa!\n");
OS_Thread::msleep(500);
}
return 0;
}
private:
bool m_quitflag;
};

在Windows上,我们写一份实现Thread_Win32.cpp

#ifdef _WIN32
#include <windows.h>
#include <process.h>
#include "Thread.h"
struct OS_Thread_Priv
{
HANDLE hThread;
};
OS_Thread::OS_Thread()
: m_Priv(NULL)
{
}
OS_Thread::~OS_Thread()
{
if(m_Priv)
{
OS_Thread_Priv* priv = (OS_Thread_Priv*) m_Priv;
delete priv;
}
}
static DWORD WINAPI OS_Thread_Proc_Win32_1(LPVOID param)
{
OS_Thread* thrd = (OS_Thread*) param;
thrd->Routine();
return 0;
}
static void OS_Thread_Proc_Win32_2(void* param)
{
OS_Thread* thrd = (OS_Thread*) param;
thrd->Routine();
}
static unsigned int WINAPI OS_Thread_Proc_Win32_3(void* param)
{
OS_Thread* thrd = (OS_Thread*) param;
thrd->Routine();
return 0;
}
int OS_Thread::Run()
{
// 创建私有结构
OS_Thread_Priv* priv = new OS_Thread_Priv;
if(!priv) return -1;
m_Priv = priv;
// 创建线程
//  DWORD nTheadId;
//  priv->hThread = _beginthreadex(NULL, NULL, OS_Thread_Proc_Win32, this,  0, &nTheadId);
//  priv->hThread = (HANDLE) _beginthread(OS_Thread_Proc_Win32, 0, this);
unsigned int thrdaddr ;
priv->hThread = (HANDLE) _beginthreadex(NULL, 0, OS_Thread_Proc_Win32_3, this, 0, &thrdaddr);
if(priv->hThread == NULL)
{
delete priv;
m_Priv = NULL;
return -1;
}
return 0;
}
void OS_Thread::Join(OS_Thread* thrd)
{
OS_Thread_Priv* priv = (OS_Thread_Priv*) thrd->m_Priv;
if(priv)
{
WaitForSingleObject(priv->hThread, INFINITE);
//      CloseHandle(priv->hThread);
// 删除资源
delete priv;
thrd->m_Priv = NULL;
}
}
void OS_Thread::Msleep(int ms)
{
::Sleep(ms);
}
void OS_Thread::Sleep(int s)
{
::Sleep(s * 1000);
}
int OS_Thread::Routine()
{
return 0;
}
#endif  //_WIN32

在Linux上的实现Thread_Linux.cpp (注间Thread_Linux.cpp和Thread_Win32.cpp是同时存在于你的项目里的,上面已经用#ifndef _WIN32给隔开了,不影响你的编译)

#ifndef _WIN32
//#if 1
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include "Thread.h"
struct OS_Thread_Priv
{
pthread_t hThread;
};
OS_Thread::OS_Thread()
: m_Priv(NULL)
{
}
OS_Thread::~OS_Thread()
{
if(m_Priv)
{
OS_Thread_Priv* priv = (OS_Thread_Priv*) m_Priv;
delete priv;
}
}
static void* OS_Thread_Proc_Linux(void* param)
{
OS_Thread* thrd = (OS_Thread*) param;
thrd->Routine();
return NULL;
}
int OS_Thread::Run()
{
// 创建私有结构
OS_Thread_Priv* priv = new OS_Thread_Priv;
if(!priv) return -1;
m_Priv = priv;
// 创建线程
if(pthread_create(&priv->hThread, NULL, OS_Thread_Proc_Linux, this) < 0)
{
delete priv;
m_Priv = NULL;
return -1;
}
return 0;
}
void OS_Thread::Join(OS_Thread* thrd)
{
OS_Thread_Priv* priv = (OS_Thread_Priv*) thrd->m_Priv;
if(priv)
{
pthread_join(priv->hThread, NULL);
// 删除资源
delete priv;
thrd->m_Priv = NULL;
}
}
void OS_Thread::Msleep(int ms)
{
//::usleep(ms * 1000);
// 好像使用nanosleep更好
timespec ts;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000000;
nanosleep(&ts, NULL);
}
void OS_Thread::Sleep(int s)
{
::sleep(s);
}
int OS_Thread::Routine()
{
return 0;
}
#endif // ! _WIN32

怎么样,如果觉得这种思路不错的话就点赞吧。(其实是参考QT的设计思路的)

C++跨平台技术 - 线程Thread相关推荐

  1. 移动互联网这十年,跨平台技术的演进及 Flutter 的未来

    作者 | 袁辉辉 责编 | 郭   芮 移动跨平台技术演进 1. 引言 移动互联网发展十余年,伴随着 Android.iOS 等智能手机的不断普及,移动端已逐步取代 PC 端,成为兵家必争之地.正所谓 ...

  2. 年终盘点跨平台技术(Hybrid、RN、Weex、Flutter)-全栈系列

    跨平台技术发展的三个阶段 第一阶段是混合开发的web容器时代 为了解决原生开发的高成本.低效率,出现了Hybrid混合开发 原生中嵌入依托于浏览器的WebView Web浏览器中可以实现的需求在Web ...

  3. 并发基础篇(六):线程Thread类的start()方法和run()方法

    点个赞,看一看,好习惯!本文 GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了 3 个月总结的一线大厂 Java 面试总结,本 ...

  4. 移动开发的跨平台技术发展史 | 技术头条

    作者 | 刘望舒 责编 | 伍杏玲 跨平台技术的诞生 我是2010年开始从事的Android开发,当时会Android和iOS开发的很少,也不火,所有人都在"摸着河底过河".项目更 ...

  5. 移动端跨平台技术总结

    概述 曾经大家以为在手机上可以像桌面那样通过 Web 技术来实现跨平台开发,却因为性能或其他问题而放弃,不得不针对不同平台开发多个版本.这也违背了跨平台开发的初衷.而React Native让跨平台移 ...

  6. 进程process和线程thread应用和区别——Python学习笔记12

    Subprocess subprocess主要是在Python中执行外部的程序和命令.在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序. subpr ...

  7. .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调、APM、EAP、TPL、aysnc、await

    windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,CLR(公共语言运行库)为该进程创建了一个线程,该线 ...

  8. Flutter 沙龙回顾 | 跨平台技术趋势及字节跳动 Flutter 架构实践

    11 月 23 日,字节跳动技术沙龙 | Flutter 技术专场 在北京后山艺术空间圆满结束.我们邀请到字节跳动移动平台部 Flutter 架构师袁辉辉,Google Flutter 团队工程师 J ...

  9. 从各大跨平台技术说开去,我们真的需要虚拟 DOM 吗?

    前言 你有没有留意到?优秀的解决方案思想都是相通的:当你研究 Flutter 渲染原理时会发现 Flutter Rendering 层类似于 React 中的虚拟 DOM,当你去看 Weex 工作原理 ...

最新文章

  1. Linux下查找nginx配置文件路径
  2. 网络工程师_TCP握手之类的
  3. 一个框架解决机器学习大部分问题!
  4. 人脸识别不只是隐私问题 信息泄露面临更大安全隐患
  5. Can’t connect to local MySQL server through socket的解决方法
  6. c语言日期编程,C语言编程计算第二天日期示例代码
  7. 操作系统原理:全局页面置换算法、工作集页置换、常驻集页置换、抖动问题
  8. matlab求两向量夹角_高中数学《平面向量的数量积》说课稿
  9. 大学校运会计算机专业方阵,校运动会方阵策划案
  10. hadoop的python框架指南_Python之——用Mrjob框架编写Hadoop MapReduce程序(基于Hadoop 2.5.2)...
  11. 阿里云成为首个通过“虚拟化云平台性能测试(大规模)”的云厂商
  12. React之state总结
  13. linux-mysql忘记密码解决办法-适用5.76
  14. html中遍历表单,萌新提问!!!如何用for循环循环表单?
  15. 字符串格式连接sqlserver数据库的字段概念解释
  16. 多种方式99.9%解决从PDF复制文字后乱码问题
  17. 广电优点家庭服务器怎么无线桥接,路由器有线桥接和无线桥接哪个好一点?
  18. 【业务知识】金融、银行业务知识点(转载)
  19. Problem_1 小鸡啄米
  20. 101shell脚本

热门文章

  1. 自学Android开发 AES加密
  2. wordcloud 配置项_wordcloud从安装到入门
  3. 【单片机基础】C51语言基础
  4. devexpress html编辑器,DevExpress使用教程:富文本编辑器RichEditControl
  5. 驱动开发之 LED(for mini2440)
  6. Python 最简单的微信刷屏
  7. 2012春节回乡见闻
  8. 【学习技巧】——怎样改掉学习上的坏习惯
  9. 行思工作室官网移动端前端开发笔记
  10. 诗歌(1)—定风波(常羡)