正文

第十七课:多线程2007-09-26 19:02:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/29684.html

分享到:

第十七课:多线程 一、概念: 进程:一个进程就是一个运行的程序,它有独立的内存、文件句柄和其他系统资源。当启动一个进程时,操作系统会为此进程建立一个4GB的地址空间,进程是操作系统分配内存地址空间的单位。 线程:是操作系统分配处理器时间的最基本单元。所以一个进程必须包含一个线程,我们称之为主线程。如果需要,进程可以产生更多的线程,让CPU在同一时间执行 不同段落的代码。 二、举例: 1.  在单线程中执行多个死循环: 建立一个控制台工程,加入一个cpp文件,编写如下代码: #include "stdio.h" void fun() {     while(1)     {         printf("thread 2 is rurnning!\n");     } } void main() {     fun();     while(1)     {         printf("thread 1 is running!\n");     } } 此时只能打出thread 2 is rurnning!,因为CPU总是在执行fun函数的代码 。没有机会向下执行其余代码。 2.  在单线程中执行多个死循环: #include "stdio.h" #include "windows.h" DWORD WINAPI fun(LPVOID lpParameter) {     while(1)     {         printf("thread 2 is rurnning!\n");     } } void main() { CreateThread(NULL,0,fun,0,0,0); while(1)     {         printf("thread 1 is running!\n");     } } 此时“thread 1 is rurnning!”,“thread 2 is rurnning!”都能打出来,两个死循环在同时运行。 三、编写一个聊天程序: 1.  建立一个基于对话框的MFC工程,删除提示用的标签控件。加入一个用于显示聊天对方发来的信息的列表框,一个用于输入输入发送给别人的信息的文本框,一个用于输入IP地址的IP Address控件。 2.  定义一个成员变量                 SOCKET  m_sockChat;    3.  在对话框中加入一个成员函数InitSocket(),对m_sockChat进行初始化:     m_sockChat=socket(AF_INET,SOCK_DGRAM,0);     SOCKADDR_IN addrChat;     addrChat.sin_family=AF_INET;     addrChat.sin_port=htons(3000);     addrChat.sin_addr.S_un.S_addr=htonl(INADDR_ANY);     bind(m_sockChat,(SOCKADDR*)&addrChat,sizeof(SOCKADDR)); 4.  加入OnOK函数,注释其中的CDialog::OnOK();语句,然后加入代码:     CString str;     GetDlgItemText(IDC_EDIT1,str);   //得到用户在文本框中输入的字符串     SOCKADDR_IN addrDest;     addrDest.sin_family=AF_INET;     addrDest.sin_port=htons(3000);     DWORD dwIP;     ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);                     //得到用户在IP地址控件中输入的地址     addrDest.sin_addr.S_un.S_addr=htonl(dwIP);  sendto(m_sockChat,str,str.GetLength(), 0,(SOCKADDR*)&addrDest,sizeof(SOCKADDR));                                     //发送数据到达指定的计算机     SetDlgItemText(IDC_EDIT1,"");                     //将文本框清空 5.  定义一个结构体,用于向线程函数传递参数: struct RECVPARAM {     SOCKET sock;     HWND   hwnd; }; 6.  在对话框的OnInitDialog()函数中加入:     InitSocket();              //初始化socket     ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->SetAddress(192,168,8,255);                             //设置IP地址控件的初始地址     RECVPARAM *precvparam=new RECVPARAM();     precvparam->sock=m_sockChat;     precvparam->hwnd =this->m_hWnd;     ::CreateThread(NULL,0,recvproc,(LPVOID)precvparam,0,0);                                         //启动一个线程,在线程函数中接收数据 7.  定义线程函数: DWORD WINAPI recvproc(LPVOID lpParameter) {       SOCKET sockChat=((RECVPARAM*)lpParameter)->sock;     HWND   hwnd=((RECVPARAM*)lpParameter)->hwnd; //取出传递进来的参数     detele (RECVPARAM*)lpParameter;    char buf[1024];         //定义用于接收数据的缓冲区     SOCKADDR_IN addrSrc;        int len,x;     char *str;     while (1)     {         memset(buf,0,1024);     //清空缓冲区         len=sizeof(SOCKADDR);       recvfrom(sockChat,buf,1024,0,(SOCKADDR*)&addrSrc,&len);                             //接收数据         sprintf(buf,"%s:%s:%d",buf, inet_ntoa(addrSrc.sin_addr),ntohs(addrSrc.sin_port));                 //得到对方的IP地址和端口号         x=strlen(buf);          str=new char[x+1];               strcpy(str,buf);        //将得到的数据转存          ::PostMessage(hwnd,WM_USER+1,0,(LPARAM)str);                                 //向指定的窗口发送消息     } } 8.  在对话框的消息映射表中添加: ON_MESSAGE(WM_USER+1, OnRecvData) 9.  在对话框中添加成员函数OnRecvData: LRESULT CChatDlg::OnRecvData(WPARAM wParam, LPARAM lParam) {     ((CListBox*)GetDlgItem(IDC_LIST1))->InsertString(0,(char*)lParam);                         //将接收到的信息加入列表框中     delete (char*)lParam;  //释放在线程中用new分配的空间     return 1; }

阅读(9453) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册