线程的初步认识——2011-7-7

     1、真正完成代码执行的是线程,而进程只是线程的容器,或者说是线程的执行环境。

     2、当创建一个进程时,操作系统会自动创建这个进程的第一个线程,即主线程。

     3、线程的组成:

                                 1)内核对象:操作系统用它来对线程实施管理,内核对象也是系统用来存放线程统计信息的地方。

                                 2)线程栈:它用于维护线程在执行代码时需要的所有函数参数和局部变量。

     4、新线程可以访问进程的内核对象的所有句柄,进程中所有内存和在这个相同的进程中的所有其它线程的堆栈。

     5、线程只有一个内核对象和一个栈,保留的记录很少,因此所需的内存也很少,由于线程需要的开销比进程少,因此在编程中经常采用多线程来解决编程问题,而尽量避免创建新的进程。而且进程间切换时,需要交换整个地址空间,而线程之间的切换只是执行环境的改变,因此效率很高。

     6、线程运行,操作系统为每一个运行的线程安排一定的CPU时间——时间片。

     7、static HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa,   //指向LPSECURITY_ATTRIBUTES  结构体 的指针。

                                                                  DWORD dwStackSize,                       //设置线程初始栈的大小

                                                                  LPTHREAD_START_ROUTINE pfnThreadProc,  // 指向应用程序定义的 LPTHREAD_START_ROUTINE 类型的函数的指针

                                                                  void* pvParam,           //上面函数命令行参数

                                                                   DWORD dwCreationFlags,  // 设置用于控制线程创建的附加标记, CREATE_SUSPENDED  

                                                                                                                    //创建后处于暂停状态直到程序调用Resume Thread 函数为止,

                                                                                                                    //0 创建后立即运行。

                                                                   DWORD* pdwThreadId   )    // 这个参数是一个返回值,它指向一个变量,用来接收线程ID

      8、例子:

#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;


void main()
{
 HANDLE hThread1;
 HANDLE hThread2;

// 第一个参数 NULL 说明使用默认安全性

// 第二个参数  0  让新线程采用与调用线程一样的栈大小

// 第三个参数  Fun1Proc 指定线程hThread1入口函数的地址

// 第四个参数 NULL 传递给函数的参数

// 第五个参数  0 创建后立即运行。

// 第六个参数  NULL 新线程ID,不需要,所以为NULL
 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
 hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);

// 关闭新线程的句柄,其实这个函数并没有中止线程,
 CloseHandle(hThread1);
 CloseHandle(hThread2);  

//Sleep() 这个函数是使调用线程暂停自己的运行,直到指定的时间间隔过去为止,单位为毫秒。

 Sleep(1000);

}

// 线程hThread1 运行的函数

DWORD WINAPI Fun1Proc(
  LPVOID lpParameter   // thread data
)
{
    if(tickets>0)
      {
       cout<<"thread1 sell ticket : "<<tickets--<<endl;
      }
    else
          break;
 }
 cout<<"thread1 is running"<<endl;

 return 0;
}

 

// 线程hThread1 运行的函数

DWORD WINAPI Fun2Proc(
  LPVOID lpParameter   // thread data
)
{
    if(tickets>0)
      {
       cout<<"thread2 sell ticket : "<<tickets--<<endl;
      }
     else
             break;
 }

   cout<<"thread2 is running"<<endl;
   return 0;
}

 

/***************************************************************************************************

上面程序有个致命的错误,两个线程同时使用一个全局变量,会导致变量不同步问题,如果线程1 运行到if(tickets>0)  ——这时tickets == 1 ,而因为没有减1 ,刚好时间片由到了,那么就停止线程1 ,转而去运行线程2 ,这样线程2运行完时,tickets == 0,在转到线程1被暂停的地方继续去运行。这样就会出现 0 的情况。

*****************************************************************************************************/

                                

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值