我对线程有点迷糊
一个简单代码 下面是2个线程函数 实际运行的结果是交替出现的 fun1打印一次 fun2打印一次我的理解是这样的 ,
在fun1函数内 执行到WaitForSingleObject(et,INFINITE); 当fun1请求到事件et所有权后 把事件et设置为无信号状态 接着睡眠1毫秒
执行fun2函数内的 对et事件的请求所有权 此时为无信号所以请求不到 接着返回fun1函数内 打印出字符串 fun1 100
接着执行SetEvent(et); 设置事件为有信号状态
fun1函数是一段while循环 我理解是会一直执行fun1函数 打印的都是 fun1的内容 不会打印出fun2的内容但结果是交替打印出现的 问题一: 是不是fun1的时间片到啦 接着就轮到fun2函数执行 fun2时间片到啦就轮到fun1 就是这样交替运行啊? 还是什么啊? 问题二: 线程是什么时候运行的啊? 是启动程序后就自动运行啦 还是非要主线程Sleep一段时间 才会运行啊?问题三: 时间片的大小系统是怎么分配的啊?
哪位大侠帮我理清这3个问题啊 感激不尽!
HANDLE et;
int n=100;void main()
{
..................
..................
et=CreateEvent(NULL,FALSE,FALSE,NULL);
SetEvent(et);
Sleep(4000);
CloseHandle(et);
}//以下是线程函数
DWORD WINAPI fun1(LPVOID lpParameter)
{
while(1)
{
WaitForSingleObject(et,INFINITE);
if(n>0)
{
Sleep(1);
cout<<"fun1 "<<n--<<endl;
}
else
break;
SetEvent(et);
}
return 0;}DWORD WINAPI fun2( LPVOID lpParameter )
{
while(1)
{
WaitForSingleObject(et,INFINITE);
if(n>0)
{
Sleep(1);
cout<<"fun2 "<<n--<<endl;
}
else
break; SetEvent(et);
}
return 0;}
一个简单代码 下面是2个线程函数 实际运行的结果是交替出现的 fun1打印一次 fun2打印一次我的理解是这样的 ,
在fun1函数内 执行到WaitForSingleObject(et,INFINITE); 当fun1请求到事件et所有权后 把事件et设置为无信号状态 接着睡眠1毫秒
执行fun2函数内的 对et事件的请求所有权 此时为无信号所以请求不到 接着返回fun1函数内 打印出字符串 fun1 100
接着执行SetEvent(et); 设置事件为有信号状态
fun1函数是一段while循环 我理解是会一直执行fun1函数 打印的都是 fun1的内容 不会打印出fun2的内容但结果是交替打印出现的 问题一: 是不是fun1的时间片到啦 接着就轮到fun2函数执行 fun2时间片到啦就轮到fun1 就是这样交替运行啊? 还是什么啊? 问题二: 线程是什么时候运行的啊? 是启动程序后就自动运行啦 还是非要主线程Sleep一段时间 才会运行啊?问题三: 时间片的大小系统是怎么分配的啊?
哪位大侠帮我理清这3个问题啊 感激不尽!
HANDLE et;
int n=100;void main()
{
..................
..................
et=CreateEvent(NULL,FALSE,FALSE,NULL);
SetEvent(et);
Sleep(4000);
CloseHandle(et);
}//以下是线程函数
DWORD WINAPI fun1(LPVOID lpParameter)
{
while(1)
{
WaitForSingleObject(et,INFINITE);
if(n>0)
{
Sleep(1);
cout<<"fun1 "<<n--<<endl;
}
else
break;
SetEvent(et);
}
return 0;}DWORD WINAPI fun2( LPVOID lpParameter )
{
while(1)
{
WaitForSingleObject(et,INFINITE);
if(n>0)
{
Sleep(1);
cout<<"fun2 "<<n--<<endl;
}
else
break; SetEvent(et);
}
return 0;}
如果是可调度的,时间片到了,自然就运行了.问题三: 时间片的大小系统是怎么分配的啊?
windows下可能是20毫秒
你的代码如下:
DWORD WINAPI fun1(LPVOID lpParameter)
{
while(1)
{
WaitForSingleObject(et,INFINITE); //等待et有信号
if(n>0)
{
Sleep(1);
cout < <"fun1 " < <n-- < <endl;
}
else
break;
SetEvent(et); //使et有信号,但是此时fun1线程函数还处于执行状态,必须执行结束后
//才可以继续等待et,所以此时fun2线程函数会执行,以下道理是一样的,
//所以你会看到打印是连续的,如果你想看到打印是不连续的,你可以通过
//修改Sleep的参数,比如你让fun1休眠50ms,而让fun2休眠90ms,这时你
//就会看到fun1会随机的多打印一次
}
return 0; }
{
while(1)
{
WaitForSingleObject(et,INFINITE); //这里等待的时候, 函数就让出了cpu的使用权。所以会执行 函数2。 最好加个if语句判断下返回值。
if(n>0)
{
Sleep(1);
cout < <"fun1 " < <n-- < <endl;
}
else
break;
SetEvent(et);
}
return 0; }
======================================
这个是由系统的线程调度程序来处理的,没有相关的官方说明,所以不好说,对fun1和fun2来说,它们的执行有很大的随机性,即fun1在任何时候都可能会停止,fun2也是这样,而且线程的调度是对整个系统的线程fun1停止后,不一定就执行fun2.
问题二: 线程是什么时候运行的啊? 是启动程序后就自动运行啦 还是非要主线程Sleep一段时间 才会运行啊?
========================
如果你不开多线程,主线程启动就会运行,如果开多线程的话,CreateThread之后,子线程就有可能被执行,是有可能,到底执不执行有很大的随机性。
问题三: 时间片的大小系统是怎么分配的啊?
================
这个不知道
差不多是你理解的样子。线程是系统统一调度的,一个线程运行一段时间后,由系统调度切换运行系统中的另一线程,如果有多个处理器,可以同时在每个处理器中各运行一个线程。问题二: 线程是什么时候运行的啊? 是启动程序后就自动运行啦 还是非要主线程Sleep一段时间 才会运行啊?
创建的时候如果没有指定CREATE_SUSPENDED标志,创建后就自动运行。问题三: 时间片的大小系统是怎么分配的啊?
目前的Windows都是10ms,这一点并不重要。你应该先创建事件,然后创建线程。
------------------------------------------------------------------------------------
默认情况下,对每个线程的调度是公平的。对于就绪队列中的所有线程根据优先级的次序一次获得时间片。对内核对象的等待理论上是依赖于等待该对象的先后顺序来触发。lz的两个线程不论当前运行的是哪个,另一个线程就处于等待Event对象的情况,所以应该会在SetEvent之后先获得通知。
问题二: 线程是什么时候运行的啊? 是启动程序后就自动运行啦 还是非要主线程Sleep一段时间 才会运行啊?
------------------------------------------------------------------------------------
创建线程的时候,没有设置参数将它挂起的话,就进入了就绪状态。只要有了时间片就能运行了。跟主线程Sleep没关系。
问题三: 时间片的大小系统是怎么分配的啊?
------------------------------------------------------------------------------------
Windows2000和xp下大概是20ms,如果是Server版的话,时间片会略长一些以便减少频繁调度的性能损失。
可调度就是可以给分配时间的,不可调度就是线程是挂起的,或者是等待某些资源,事件等,这时候不分配cpu时间..........