区别:程序和进程、线程(轻量级进程)的概念;
利用window库函数建立一个主线程和子线程的一个轮流执行
#include <windows.h>
#include <iostream.h>
DWORD WINAPI func1proc(LPVOID lpParameter);
int index=10;
void main()
{
HANDLE hthread1;
hthread1=CreateThread(NULL,0,func1proc,NULL,0,NULL);//创建一个线程
CloseHandle(hthread1);//关闭句柄,不关闭线程,减少引用计数,计数为0释放;
cout<<"main thread is running\n"<<endl;
Sleep(2000);//主进程睡眠,子进程才能执行,否则子进程不能获得执行;
}
DWORD WINAPI func1proc(
LPVOID lpParameter // thread data
)
{
cout<<"Thread1 is running!\n"<<endl;
return 0;
}
本质是程序的执行就是主线程休眠之后,将控制权交给子进程的,子进程然后执行;
多线程注重访问共享变量时的互斥锁的问题
#include <windows.h>
#include <iostream.h>
DWORD WINAPI func1proc(LPVOID lpParameter);
DWORD WINAPI func2proc(LPVOID lpParameter);
int index=0;
int tickets=100;
HANDLE mutex;
void main()
{
HANDLE hthread1;
HANDLE hthread2;
hthread1=CreateThread(NULL,0,func1proc,NULL,0,NULL);//创建一个线程
hthread2=CreateThread(NULL,0,func2proc,NULL,0,NULL);
CloseHandle(hthread1);//关闭句柄,不关闭线程,减少引用计数,计数为0释放;
//while(index++<100)
//cout<<"main thread is running\n"<<endl;
mutex=CreateMutex(NULL,false,NULL);//创建互斥锁
Sleep(2000);//主进程睡眠,子进程才能执行,否则子进程不能获得执行;
}
DWORD WINAPI func1proc(
LPVOID lpParameter // thread data
)
{
while(true)
{
WaitForSingleObject(mutex,INFINITE);//得到mutex互斥对象,互斥对象线程ID设置为该线程ID,
if (tickets>0)
{
Sleep(1);
cout<<"thread1 sells tickets:"<<tickets--<<endl;
}
else
break;
ReleaseMutex(mutex);//释放互斥锁,因为他们访问了一个统一的全局变量ticket
}
return 0;
}
//一旦一个线程正常结束时,就把互斥对象的内部ID设置为0;
DWORD WINAPI func2proc(
LPVOID lpParameter // thread data
)
{
while(true)
{
WaitForSingleObject(mutex,INFINITE);
Sleep(1);
if (tickets>0)
{
cout<<"thread2 sells tickets:"<<tickets--<<endl;
}
else
break;
ReleaseMutex(mutex);
}
return 0;
}
c创建一个机遇对话框的聊天窗口;
首先设计好dialog窗口 包含2个组框,2个编辑窗口。一个按钮,一个IP编辑窗口;
2,然后在BOOL CChatApp::InitInstance()中添加标准socket的绑定函数,注意头问价加入socket。h
BOOL CChatApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox("加载套接字失败!");
return FALSE;
}
3在CChatDlg类里面添加成员变量和成员函数,并在OnInitDialog()调用次初始化函数;
BOOL CChatDlg::InitSocket()
{
m_socket=socket(AF_INET,SOCK_DGRAM,0);
if (INVALID_SOCKET==m_socket)
{
MessageBox("套接字创建失败");
return FALSE;
}
SOCKADDR_IN addrsock;
addrsock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrsock.sin_family=AF_INET;
addrsock.sin_port=6000;
//bind到IP和端口上;
int retval;
retval=bind(m_socket,(sockaddr*)&addrsock,sizeof(sockaddr));
if (SOCKET_ERROR==retval)
{
closesocket(m_socket);
MessageBox("套接子绑定失败");
return FALSE;
}
return TRUE;
}
3创建线程的函数,因为createthread函数只能传入一个参数,所以利用传入结构体指针形式传入2个参数;
定义结构体:
struct RecvParm
{
SOCKET sock;
HWND hwdn;
};
初始化,并调用创建线程函数(CChatDlg::OnInitDialog())
RecvParm *pRecvParam=new RecvParm;//定义一个将要传入到Createthread里面的参数
pRecvParam->sock=m_socket;//初始化socket
pRecvParam->hwdn=m_hWnd;//和窗口有关的都一个一个变量保存窗口的句柄
HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
CloseHandle(hThread);//关闭句柄,减少计数;
实现线程处理函数RecvProc()定义为起一个成员函数,注意此处为静态函数,因为不是的话,会产生一个参数传递错误;
此聊天窗口程序没有调通;不知为什么窗口不显式输入内容