多线程和socket的知识点

什么叫进程?
程序是计算机指令的集合,它以文件的形式存储在磁盘上。
进程:通常被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动。
进程由两个部分组成:
1、操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。
2、地址空间。它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆分配空间。


进程和程序的区别?
进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源
程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源。

进程从来不执行任何东西,它只是线程的容器。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,此线程负责执行包含在进程的地址空间中的代码。

单个进程可能包含若干个线程,这些线程都“同时” 执行进程地址空间中的代码。

每个进程至少拥有一个线程,来执行进程的地址空间中的代码。
当创建一个进程时,操作系统会自动创建这个进程的第一个线程,称为主线程。此后,该线程可以创建其他的线程。


进程地址空间
系统赋予每个进程独立的虚拟地址空间。对于32位进程来说,这个地址空间是4GB。

每个进程有它自己的私有地址空间。
进程A可能有一个存放在它的地址空间中的数据结构,地址是0x12345678,
而进程B则有一个完全不同的数据结构存放在它的地址空间中,地址是0x12345678。
当进程A中运行的线程访问地址为0x12345678的内存时,这些线程访问的是进程A的数据结构。
当进程B中运行的线程访问地址为0x12345678的内存时,这些线程访问的是进程B的数据结构。
进程A中运行的线程不能访问进程B的地址空间中的数据结构,反之亦然。

4GB是虚拟的地址空间,只是内存地址的一个范围。在你能成功地访问数据而不会出现非法访问之前,必须赋予物理存储器,或者将物理存储器映射到各个部分的地址空间。
4GB虚拟地址空间中,2GB是内核方式分区,供内核代码、设备驱动程序、设备I/O高速缓冲、非页面内存池的分配和进程页面表等使用,
而用户方式分区使用的地址空间约为2GB,这个分区是进程的私有地址空间所在的地方。
一个进程不能读取、写入、或者以任何方式访问驻留在该分区中的另一个进程的数据。对于所有应用程序来说,该分区是维护进程的大部分数据的地方。

线程
线程由两个部分组成:
 1、线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。
 2、线程堆栈,它用于维护线程在执行代码时需要的所有参数和局部变量。
当创建线程时,系统创建一个线程内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构。可以将线程内核对象视为由关于线程的统计信息组成的一个小型

数据结构。
线程总是在某个进程环境中创建。系统从进程的地址空间中分配内存,供线程的堆栈使用。新线程运行的进程环境与创建线程的环境相同。因此,新线程可以访问进程的内核对象的所有句柄

、进程中的所有内存和在这个相同的进程中的所有其他线程的堆栈。这使得单个进程中的多个线程确实能够非常容易地互相通信。
线程只有一个内核对象和一个堆栈,保留的记录很少,因此所需要的内存也很少。
因为线程需要的开销比进程少,因此在编程中经常采用多线程来解决编程问题,而尽量避免创建新的进程。

线程运行
操作系统为每一个运行线程安排一定的CPU时间 —— 时间片。系统通过一种循环的方式为线程提供时间片,线程在自己的时间内运行,因时间片相当短,因此,给用户的感觉,就好像线程

是同时运行的一样。
如果计算机拥有多个CPU,线程就能真正意义上同时运行了。


HANDLE CreateThread (
  SEC_ATTRS SecurityAttributes,
  ULONG StackSize,
  SEC_THREAD_START StartFunction,
  PVOID ThreadParameter,
  ULONG CreationFlags,
  PULONG ThreadId
);

VOID Sleep(
  DWORD dwMilliseconds   // sleep time
);--->让此线程放弃拥有权,交至其他线程


互斥对象

互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。
互斥对象包含一个使用数量,一个线程ID和一个计数器。
ID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。

HANDLE CreateMutex(
  LPSECURITY_ATTRIBUTES lpMutexAttributes,  // SD
  BOOL bInitialOwner,                       // initial owner----->是否让主线程来占据所有权
  LPCTSTR lpName                            // object name------》为互斥对象命名名称
);
DWORD WaitForSingleObject(------------------------》
  HANDLE hHandle,        // handle to object
  DWORD dwMilliseconds   // time-out interval
);

BOOL ReleaseMutex(
  HANDLE hMutex   // handle to mutex
);

售票程序
#include <windows.h>
#include <iostream.h>

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
);

DWORD WINAPI Fun2Proc(
  LPVOID lpParameter   // thread data
);
int index=0;
int tickets=100;
HANDLE hMutex;
void main()
{
 HANDLE hThread1;
 HANDLE hThread2;
 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
 hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
 CloseHandle(hThread1);
 CloseHandle(hThread2);

// hMutex=CreateMutex(NULL,TRUE,NULL);
 hMutex=CreateMutex(NULL,TRUE,"tickets");
 if(hMutex)
 {
  if(ERROR_ALREADY_EXISTS==GetLastError())
  {
   cout<<"only one instance can run!"<<endl;
   return;
  }
 }
 WaitForSingleObject(hMutex,INFINITE);
 ReleaseMutex(hMutex);
 ReleaseMutex(hMutex);

 Sleep(4000);
}

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
)
{
 while(TRUE)
 {
  WaitForSingleObject(hMutex,INFINITE);
  if(tickets>0)
  {
   Sleep(1);
   cout<<"thread1 sell ticket : "<<tickets--<<endl;
  }
  else
   break;
  ReleaseMutex(hMutex);
 }

/* WaitForSingleObject(hMutex,INFINITE);
 cout<<"thread1 is running"<<endl;
*/
 return 0;
}

DWORD WINAPI Fun2Proc(
  LPVOID lpParameter   // thread data
)
{
 while(TRUE)
 {
  WaitForSingleObject(hMutex,INFINITE);
  if(tickets>0)
  {
   Sleep(1);
   cout<<"thread2 sell ticket : "<<tickets--<<endl;
  }
  else
   break;
  ReleaseMutex(hMutex);
 }


/* WaitForSingleObject(hMutex,INFINITE);
 cout<<"thread2 is running"<<endl;
 */
 return 0;
}

加载套接字
BOOL AfxSocketInit(
WSADATA* lpwsaData = NULL );
应用如下:
BOOL CMyApp::InitInstance()
{
  //Default Appwizard code.
  if(!AfxSocketInit())
    AfxMessageBox("Failed to Initialize Sockets",MB_OK| MB_ICONSTOP);
  return CWinApp::InitInstance();
}


CIPAddressCtrl::GetAddress

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章