mfc多线程串口通信_python进程和线程之间通信

mfc多线程串口通信_python进程和线程之间通信AfxBeginThead全局变量参数传递消息传递线程通信目录(?)[-]线程间的通信线程之间的通信简介全局变量方式参数传递方式消息传递方式线程同步法线程间的通信1.线程之间的通信简介一般而言,在一个应用程序中(即进程),一个线程往往不是孤立存在的,常常需要和其它线程通信,以执行特定的任务。如主线程和次线程,次线程与次线程,工作线程和

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用



线程间的通信

1.线程之间的通信简介

一般而言,在一个应用程序中(即进程),一个线程往往不是孤立存在的,常常需要和其它线程通信,以执行特定的任务。如主线程和次线程,次线程与次线程,工作线程和用户界面线程等。这样,线程与线程间必定有一个信息传递的渠道。这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的。线程间的通信涉及到4个问题:

(1) 线程间如何传递信息

(2)  线程之间如何同步,以使一个线程的活动不会破坏另一个线程的活动,以保证计算结果的正确合理

(3)  当线程间具有依赖关系时,如何调度多个线程的处理顺序

(4)  如何避免死锁问题

在windows系统中线程间的通信一般采用四种方式:全局变量方式、消息传递方式、参数传递方式和线程同步法。下面分别作介绍。

2.全局变量方式

由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量。对于标准类型的全局变量,我们建议使用volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变。

实例演示

该实例采用全局变量来控制时间显示线程的显示格式,比较简单。

主要的代码如下:

.h头文件

//线程函数声明

DWORD WINAPIThreadProc(LPVOIDlpParam);

protected:

HANDLE m_hThread;//线程句柄

      DWORD  m_nThread;//线程ID

.cpp实现文件

volatileBYTE m_nShowFlag = 31;//定义全局变量,用于控制显示时间的格式。volatile 修饰符的作用是告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中。

//创建显示时间的线程,参数无

 m_hThread =CreateThread(NULL,0,ThreadProc,NULL,0,&m_nThread);

//线程执行函数,用于实时显示时间,并按规定格式显示

DWORD WINAPIThreadProc(LPVOID lpParam)

{

      while(m_nShowFlag

      {

           CTime time

           CString strTime,strFormat

           time=CTime::GetCurrentTime();

           strFormat = “%H:%M”;

           if (m_nShowFlag&2)

           {
//日期

                 strFormat = “%Y-%m-%d” + strFormat;

           }

           if (m_nShowFlag&4)

           {
//秒钟

                 strFormat += “:%S”;

           }

           if (m_nShowFlag&8)

           {
//周数

                 strFormat += “%W”;

           }

           if (m_nShowFlag&16)

           {
//星期

                 strFormat += “%a”;

           }

      strTime=time.Format(strFormat); 

      ::SetDlgItemText(AfxGetApp()->m_pMainWnd->m_hWnd,IDC_STATIC_TIME,strTime); 

      Sleep(100); 

      } 

      return 0;

}

运行效果:

mfc多线程串口通信_python进程和线程之间通信

工程源码下载地址:

http://download.csdn.net/detail/cbnotes/4962315

欢迎大家修改和指正。

注意事项:

(1)  全局变量最好放在.CPP文件的起始处,而不要放在.h头文件中,否则将出现重复链接的编译错误。定义全局变量时最好显式初始化,默认初始值为零

(2)  注意语句

::SetDlgItemText(AfxGetMainWnd()->m_hWndIDC_STATIC_TIME,strTime);在VC6.0中可以通过,但在VC2008却出错,这是因为在VC2008中不支持AfxGetMainWnd()->m_hWnd来获取HWND,但可以采AfxGetApp()->m_pMainWnd->m_hWnd来获取。所以上面的语句更改为:

::SetDlgItemText(AfxGetApp()->m_pMainWnd->m_hWnd,IDC_STATIC_TIME,strTime); 

(3)  用全局变量方式来实现多线程的通信比较简单实用,单注意最好不要多个线程对它进行修改,否则将可能出错,这将在后面会具体讲解。

3.参数传递方式

该方式是线程通信的官方标准方法,多数情况下,主线程创建子线程并让其子线程为其完成特定的任务,主线程在创建子线程时,可以通过传给线程函数的参数和其通信,三类创建线程的函数都支持参数的传递(哪三类?看前面的介绍吧!)。所传递的参数是一个32位的指针,该指针不但可以指向简单的数据,而且可以指向结构体或类等复杂的抽象数据类型。

实例演示

下面将分别简单演示三类创建线程时提供参数传递的方法。

主要的代码如下:

.h头文件

//线程函数声明

DWORD WINAPI ThreadFunc1(LPVOID lpParam);//线程函数

void  ThreadFunc2(void *pArg);           //线程函数

UINT  ThreadFunc3(LPVOID lpParam);//线程函数

//全局函数

POINT GetRandPoint();//得到随机点的坐标

//结构体定义,用于向线程传递多个参数

struct threadInfo

{

      HWND        hWnd;//主窗口句柄

      COLORREF    clrPen;//画笔颜色

};

.cpp实现文件

//开始创建线程:创建个线程

void CMultThreadComm2Dlg::OnStart(void)

{

      //线程:使用win32 API 创建:实时显示时间

      m_hThread1 = CreateThread(NULL,0,ThreadFunc1,&m_stTime.m_hWnd,0,NULL);//

      //线程:使用CRT 创建:随机画线

      m_info.hWnd = m_hWnd;

      m_info.clrPen =RGB(255,0,0);

      _beginthread(ThreadFunc2,0,&m_info);

      //线程:使用MFC线程函数创建:显示进度

      m_pThread = AfxBeginThread(ThreadFunc3,&m_ctrlProgress);

}

//停止/开始

void CMultThreadComm2Dlg::OnBnClickedButton1()

{

      // TODO: 在此添加控件通知处理程序代码

      CString szTitle;

      GetDlgItemText(IDC_BUTTON1,szTitle);

      if (szTitle == 停止”)

      {
//停止

           g_bRun = false;

           SetDlgItemText(IDC_BUTTON1,开始”);

      }

      else

      {
//开始

           g_bRun = true;

           OnStart();

           SetDlgItemText(IDC_BUTTON1,停止”);

      }

}

//线程执行函数:实时显示当前的时间

DWORD WINAPI ThreadFunc1(LPVOID lpParam)

{

      HWND *hWnd = (HWND*)lpParam;

    //CWnd *pWnd = AfxGetApp()->m_pMainWnd;//当没有传递参数时,可以用该api实现

      CWnd *pWnd = CWnd::FromHandle(*hWnd);

      char tmpbuf[128] ={
‘0’};

      time_t t;

      while(g_bRun)

      {

           t = time(NULL);

       strftime(tmpbuf,128,“%Y-%m-%d%a %I:%M:%S %p”,localtime(&t));

          pWnd->SetWindowText(tmpbuf);

          Sleep(500); 

      }

      return 0;

}

//线程执行函数:随机画线

void ThreadFunc2(void *pArg)

{

      threadInfo *threadinfo= (threadInfo*)pArg;

      CWnd *pWnd = CWnd::FromHandle(threadinfo->hWnd);

      CDC *pDC = pWnd->GetDC();

      CPen pen(PS_SOLID,2,threadinfo->clrPen);

      pDC->SelectObject(&pen);

      pDC->SetROP2(R2_NOTXORPEN);

      while(g_bRun)

      {

           POINT StartPos= GetRandPoint();

           POINT EndPos = GetRandPoint();

           //

           CString str;

      str.Format(“%d,%d : %d,%d\n”,StartPos.x,StartPos.y,EndPos.x,EndPos.y);

           TRACE(str);

           pDC->MoveTo(StartPos);

           pDC->LineTo(EndPos);

           Sleep(100);

           pDC->MoveTo(StartPos);

           pDC->LineTo(EndPos);

           Sleep(100);

      }

      DeleteObject(pDC);

}

//线程执行函数:显示进度

UINT ThreadFunc3(LPVOIDlpParam)

{

      CProgressCtrl *pProgress= (CProgressCtrl*)lpParam;

      while(g_bRun)

      {

           pProgress->StepIt();

           Sleep(500); 

      }

      return 0;

}

//得到随机点

POINT GetRandPoint()

{

      POINT Point;

      Point.x = rand()%439;

      Point.y = rand()%208;

    return Point;

}

运行效果:

mfc多线程串口通信_python进程和线程之间通信

工程源码下载地址:

 http://download.csdn.net/detail/cbnotes/4984274

欢迎大家修改和指正。

注意事项:

(1)   注意三类线程的创建方法和各自的线程函数的格式(返回类型各不一样)。

(2)   注意三类参数的传递:单个参数、多参数(结构体),复杂参数(类)。

(3)   采用参数传递方式进行线程间的通信只适用于主线程向从线程的通信。

(4)   不知道大家看出该程序的一个BUG没有(大家可以下载工程源码,编译并运行,可以很明显的发现。),就是线程二的随机画线线程,原意是随机画线并清除,但运行发现第一次画线时总是没有被清除掉,为什么?望大家动脑,知道的可以留言,大家一起学习和讨论!

4.消息传递方式

在Windows程序设计中,应用程序的每一个线程都拥有自己的消息队列,甚至工作线程也不例外,这样一来,就使得线程之间利用消息来传递信息就变的非常简单。我们可以在一个线程的执行函数中向另一个线程发送自定义的消息来达到通信的目的。一个线程向另外一个线程发送消息是通过操作系统实现的。利用Windows操作系统的消息驱动机制,当一个线程发出一条消息时,操作系统首先接收到该消息,然后把该消息转发给目标线程,接收消息的线程必须已经建立了消息循环。该方式可以实现任意线程间的通信,所以是比较常见和通用的方式。

系统也提供了线程间发送消息的专用函数:PostThreadMessage()。用户先定义一个用户消息,在一个线程调用PostThreadMessage()函数,在消息接收线程响应该消息,大体和常用的小子响应处理差不多。只是消息映射为ON_THREAD_MESSAGE而不是ON_MESSAGE

如果线程有窗体,还可以使用通用的消息发送函数PostMessage()和SendMessage()这两个函数。注意这两则的区别,PostMessage()是异步函数,调用后函数立即返回,而SendMessage()是同步函数,要等相应的消息响应完成后才返回。

关于PostThreadMessage()、PostMessage()和SendMessage()函数介绍请参考MSDN,在此就不多吃一举了。

对于PostThreadMessage()的用法:

先定义一个用户消息,如:

#define WM_THREADMSG  WMUSER+100

在需要发送消息的线程调用PostThreadMessage()函数,如:

::PostThreadMessage(idThread,WM_THREADMSG,parm1, parm2);

或者

m_pThread->PostThreadMessage(WM_THREADMSG,parm1, parm2); 

其中: idThread为消息接受线程的ID,parm1, parm2为要传递的参数,m_pThread消息接受线程指针。

在接受消息线程中(或消息处理线程中),先定义消息响应函数,如:

afx_msg void OnThreadMessage(WPARAM wParam,LPARAM lParam);

然后在消息映射表中添加该消息的映射,如:

ON_THREAD_MESSAGE(WM_THREADMSG,OnThreadMessage)

最后,实现该消息函数,如:

//显示消息处理函数

void XXXXThread::OnThreadMessage(WPARAM wParam,LPARAM lParam)

{

      ;//消息处理

}

/

对于PostMessage()/SendMessage()的用法:和上面的差不多,略有不同。

首先也是先定义一个用户消息,如:

#define WM_THREADMSG  WMUSER+100

在需要发送消息的线程调用PostMessage()/SendMessage()函数,如:

::PostMessage(hWnd, WM_THREADMSG, parm1, parm2);//发送消息

或者

PWnd->PostMessage(WM_THREADMSG, parm1, parm2);

或者

::SendMessage(hWnd, WM_THREADMSG, parm1, parm2);//发送消息

或者

PWnd->SendMessage(WM_THREADMSG, parm1, parm2);

其中: hWnd为接受消息的窗口句柄,parm1, parm2为要传递的参数,pWnd消息接受窗口指针。

在接受消息线程中(或消息处理线程中),先定义消息响应函数,如:

afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);

然后在消息映射表中添加该消息的映射,如:

ON_MESSAGE(WM_THREADMSG, OnMyMessage)

最后,实现该消息函数,如:

//消息处理函数

LRESULT XXXXWnd::OnMyMessage(WPARAM wParam,LPARAM lParam)

{

      ;//消息处理

return 0;

}

实例演示

该实例主要时计算正整数1-N的累加,并采用单独的线程来计算累积,并创建另一个用户界面线程来实时显示累加的进度,其中涉及到一些线程间的通信,该实例主要采用了消息的方式,并结合前面已经介绍的两种通信方式,比较具有演示和学习的价值。

主要源码:

主线程头文件:

DWORD WINAPI ThreadFunc(LPVOIDlpParam);//线程函数

 

protected:

HANDLE m_hThread;//线程句柄

CProgressThread *m_pThread;//用户界面线程句柄

DWORD  m_nThreadID;//线程ID

主线程实现文件:

//开始计算

void CMultThreadComm3Dlg::OnBnClickedButton1()

{

    // TODO: 在此添加控件通知处理程序代码

    UpdateData(TRUE);//更新数据

    g_bStop = false; //重置

    m_hThread = CreateThread(NULL,0,ThreadFunc,&m_nRange,0,NULL);//创建计算线程

    GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);//防止重复计算

    SetDlgItemText(IDC_STATIC_RESULT,计算中…”);

}

 

//结果显示:两种结果:,正常,,被中途中止

LRESULT CMultThreadComm3Dlg::OnResult(WPARAMwParam,LPARAMlParam)

{

    if (wParam == 1)

    {
//被中途中止

       SetDlgItemText(IDC_STATIC_RESULT,被中止啦!”);

    }

    else

    {
//正常结束

       SetDlgItemInt(IDC_STATIC_RESULT,lParam);

    }

    GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);//使能下次计算按钮

    CloseHandle(m_hThread);//关闭线程句柄,注意一定要关闭它

    return 0;

}

 

//线程执行函数:计算

DWORD WINAPI ThreadFunc(LPVOIDlpParam)

{

    UINT *pRange =(UINT*)lpParam;//得到参数值

   long nResult= 0L;//计算结果值

    bool bStop = false;//标识是否中途被中止

    CProgressThread *m_pThread= (CProgressThread*)AfxBeginThread(RUNTIME_CLASS(CProgressThread));//创建显示进程

    m_pThread->PostThreadMessage(WM_PROGRESS,0,*pRange);//传递参数,进度条的范围

    for(int i=0;i<=*pRange;i++)//开始计算

    {

       if (g_bStop)

       {
//中途取消了

           bStop = true;

           break;//退出循环

       }

       nResult += i;

       m_pThread->PostThreadMessage(WM_PROGRESS,1,i);//进度

       Sleep(10);//为了演示效果,特意延时

    }

    //完成

    ::PostMessage(AfxGetApp()->m_pMainWnd->m_hWnd,WM_RESULT,bStop,nResult);//显示结果

    m_pThread->PostThreadMessage(WM_PROGRESS,2,0);//结束进度

    return 0;

}

累加线程头文件:

CProgressDlg *m_pProgressDlg;//进度条对话框

unsigned int m_nRange;//进度条的范围

累加线程实现文件:

BOOL CProgressThread::InitInstance()

{

    // TODO: 在此执行任意逐线程初始化

    //创建非模式进度显示对话框

    m_pProgressDlg = newCProgressDlg();

    m_pProgressDlg->Create(IDD_DIALOG1);

    m_pProgressDlg->ShowWindow(SW_SHOW);

    return TRUE;

}

BEGIN_MESSAGE_MAP(CProgressThread, CWinThread)

    ON_THREAD_MESSAGE(WM_PROGRESS, &CProgressThread::OnThreadMsg)

END_MESSAGE_MAP()

 

// CProgressThread 消息处理程序

 

//线程消息处理函数

void CProgressThread::OnThreadMsg(WPARAM wParam,LPARAM lParam)

{

    if (wParam == 0)

    {
//初始化进度条

       m_nRange = lParam;

       m_pProgressDlg->m_ProgressCtrl.SetRange(0,lParam);

    }

    else if (wParam == 1)

    {
//显示进度

       m_pProgressDlg->m_ProgressCtrl.SetPos(lParam);//显示进度

       CString str;

       str.Format(“%d%%”,int((float)lParam/m_nRange*100));

       m_pProgressDlg->m_stValue.SetWindowText(str);//显示百分数

       str.Format(计算处理中,请稍等…    %d/%d        cbNotes”,lParam,m_nRange);//显示实时的当前操作

       m_pProgressDlg->SetWindowText(str);

    }

    else

    {
//完成,退出进度条

       m_pProgressDlg->CloseDlg();//结束进程对话框

       AfxEndThread(0);//终止本线程,也可以使用PostQuitMessage(0);

    }

}

进度条对话框类

//系统消息处理

void CProgressDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    if (nID == SC_CLOSE)//关闭

    {
//拦截关闭按钮消息

       if (AfxMessageBox(确定要【终止】本次计算吗?”,MB_YESNO|MB_APPLMODAL|MB_ICONQUESTION|MB_DEFBUTTON2)==IDYES)

       {

           g_bStop = true;//中途取消操作,结束计算线程。

       }

       return;

    }

    CDialog::OnSysCommand(nID, lParam);

}

 

//关闭窗口

void CProgressDlg::CloseDlg(void)

{

    OnCancel();

}

 

//重载OnCancel():注意非模式对话框的退出

void CProgressDlg::OnCancel()

{

    // TODO: 在此添加专用代码和/或调用基类

   DestroyWindow();//

    //CDialog::OnCancel();

}

 

void CProgressDlg::PostNcDestroy()

{

    // TODO: 在此添加专用代码和/或调用基类

    CDialog::PostNcDestroy();

    delete this;

}

 

运行结果:

mfc多线程串口通信_python进程和线程之间通信

工程源码下载地址:

http://download.csdn.net/detail/cbnotes/5007011

欢迎大家修改和指正。

注意事项:

(1)  注意线程消息的映射方式:

ON_THREAD_MESSAGE(WM_PROGRESS, &CProgressThread::OnThreadMsg)

和一般的窗口消息映射不同,不要搞错了。

(2)  注意用户界面线程的退出,计算完后要记得结束该线程,有专门的函数:

AfxEndThread(0),也可以使用PostQuitMessage(0)。这两种方式都是比较安全的。不推荐强制中止线程,否则会出现意想不到的问题。

(3)  该实例还实现了执行过程按退出按钮时的处理方法,采用了全局变量的

方式来控制计算线程的中途退出,我自认为是一种比较好的控制方式。我开始采用强制中止的方式会出现消息延后的现象(就是在退出按钮的处理函数里向主线程发送消息postmessage),一直没有找到原因,有兴趣的朋友可以试试其它的退出方式供大家讨论学习。

(4)  注意非模式对话框退出的处理方法,和模式对话框的退出不一样的。

(5)用CreateThread()函数创建线程将返回一个线程句柄,通过该句柄你可以控制和操作该线程,当你不用时可以一创建该线程后就关闭该句柄,有专门的函数CloseHandle()。关闭句柄并代表关闭线程,只是你不能在外部控制该线程(比如,提前结束,更改优先级等)。在线程结束后,系统将自动清理线程资源,但并不自动关闭该句柄,所以线程结束后要记得关闭该句柄,你可能要问为什么你这么强调要关闭该句柄,是因为该句柄(HANDLE)是内核对象,内核对象的管理是操作系统管理的,具体你可以查查相关资料,我在此就不啰嗦了。

 

5.线程同步法

还可以通过线程同步来实现线程间通信。例如有两个线程,线程A写入数据,线程B读出线程A准备好的数据并进行一些操作。这种情况下,只有当线程A写好数据后线程B才能读出,只有线程B读出数据后线程A才能继续写入数据,这两个线程之间需要同步进行通信。关于线程同步的方法和控制是编写多线程的核心和难点,方法也比较多,在此就不具体讲解和实例演示,具体内容我将在接下来的文章中一一道来,敬请继续关注我的更新,谢谢。

===========================================

转载请标明出处,谢谢。http://blog.csdn.net/cbNotes

===========================================

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/188388.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • mysql8.0.25安装配置教程(windows 64位)最详细

    目录1.官网下载MySQL2.配置初始化文件my.ini3.初始化MySQL4.安装mysql服务并启动+修改密码5.配置环境变量6.部分疑难杂病7.使用连接工具连接mysql1.官网下载MySQL下载Mysql点击下载mysql.下载完成后解压到某一个文件夹(记住这个路径,一会要用到)2.配置初始化文件my.ini在根目录下创建一个txt文件,名字叫my,文件后缀为ini之后复制下面这个代码放在文件下(新解压的文件没有my.ini文件,需自行创建)以下代码除安装目录和数据的存放目录需修

  • json序列化和反序列化方法(数据整理常用的三种方式)

    以下内容是本作者从官网中看相应的教程后所做的demo,其体现了作者对相关知识点的个人理解。。作者才疏学浅,难免会有理解不到位的地方。。还请各位读者批判性对待。。。      本文主要介绍在Json数据的序列化与反序列化的过程中我经常用到的三种工具的基本使用方法,及其他们之间的比较。。。希望能够对读者们有一些帮助。。。这里介绍到的三种解析与生成Json数据的方法分别是:

  • matlab求解时滞微分方程「建议收藏」

    matlab求解时滞微分方程「建议收藏」matlab求解时滞微分方程,dde23调用格式:sol=dde23(ddefun,lags,history,tspan);–ddefun函数句柄,求解微分方程y’=f(t,y(t),y(t-τ1),…,y(t-τk))必须写成下面形式:dydt=ddefun(t,y,Z);其中t对应当前时间t,y为列向量,近似于y(…

  • conda换成中科大的源,2.更换Conda源「建议收藏」

    conda换成中科大的源,2.更换Conda源「建议收藏」#换源###1.Conda切换为清华源>condaconfig–addchannelshttps://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/>condaconfig–addchannelshttps://mirrors.tuna.tsinghua.edu.cn/anaconda/pkg…

  • 思科配置VLAN的实例

    思科配置VLAN的实例在我们上面的环境,是一个传统的网络,所有的主机都在一个广播域地址,正是这个原因,使得网络当中的广播包,给整个网络带来巨大的压力。总之,在这种情况下,同一个vlan的主机可以通信,不同一个vlan的主机不可以通信。pc2和pc4同属vlan20,(同一个vlan的主机可以通信)VLAN就是虚拟局域网的意思,它的特点是灵活性高,可扩展性高。好了,我们有关于思科配置VLAN的实例就到这里了,谢谢大家。在sw1上将相应的接口加入到相应的vlan,(在sw2上将相应的接口加入到相应的vlan,(…

  • IDEA安装教程(傻瓜式安装)

    IDEA安装教程(傻瓜式安装)IDEA安装教程1.文件下载1.idea下载2.PJ文件下载2.idea安装步骤3.PJ导包1.文件下载1.idea下载下载地址.版本为2020.1为例2.PJ文件下载下载地址.密码:d79t选择版本进行下载。2.idea安装步骤1.双击打开软件,点击Next2.选择安装目录,然后点击Next(然后会卡一会,取决于电脑性能,在此操作之间,不要着急)3.选择64位,就可以,其他选项看自己需要,然后点击Next4.无需选择,直接点击Install,5.然后点击Finish,完成

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号