请教一下semaphore如何实现线程同步和互斥的?

houpk345 2010-03-09 11:40:30
CreateSemaphore可以设置信号量初始值和最大值,ReleaseSemaphore函数的作用是增加信号量的计数,但没有减少信号量计数的值,初始值的设置又不能小于0,如何实现同步和互斥呢?习惯了unix下的信号量机制,现在遇到windows的实在转不过弯来。。。
...全文
275 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
WizardK 2010-03-09
  • 打赏
  • 举报
回复
UNIX的信号量和WINDOWS的信号量有本质上的区别吗?

如果你要互斥,就设置为0,1的信号量即可
houpk345 2010-03-09
  • 打赏
  • 举报
回复
引用 9 楼 wizardk 的回复:
引用 8 楼 houpk345 的回复:引用 7 楼 wizardk 的回复: 引用 6 楼 houpk345 的回复:终于知道问题在哪里了,原来是没了解WaitForSingleObject函数,非常感谢! 但还有一个问题,那互斥是不是应该是1,1信号量?WaitForSingleObject遇到初始值为0的信号量不阻塞吗?UNIX中的P操作-1 <0是阻塞啊... 呵呵,我说的0,1的意思是信号量的值的表示范围是[0,1],不是说初始化的时候为0 呵呵,非常感谢,我还有一个问题向讨教,有线程1,线程2,线程3三个线程,如果要求线程3在线程1和线程2都执行完之后才能执行,如何实现?我本来的想法是: HANDLE hSemaphore; hSemaphore = CreateSemaphore(NULL,-1,1,NULL); 线程1: ReleaseSemaphore(); ...... 线程2: ReleaseSemaphore(); ...... 线程3: WaitForSingleObject(hSemaphore, INFINITE); ...... 但是发现信号量的初始值不能设为-1......

信号量的初始值不能小于0
你的这个情况没必要用信号量,可以用事件的方式,理解上更清晰,非要用也可以:
HANDLE hSemaphore;
hSemaphore = CreateSemaphore(NULL,0,2,NULL);

线程1:
ReleaseSemaphore();
......

线程2:
ReleaseSemaphore();
......

线程3:
WaitForSingleObject(hSemaphore, INFINITE);
WaitForSingleObject(hSemaphore, INFINITE);// two times
......

建议你也可以参考下我的这个帖子:http://topic.csdn.net/u/20100308/16/7102875a-9103-494a-b1d0-253f1a1eba2e.html

非常感谢!
WizardK 2010-03-09
  • 打赏
  • 举报
回复
引用 8 楼 houpk345 的回复:
引用 7 楼 wizardk 的回复:
引用 6 楼 houpk345 的回复:终于知道问题在哪里了,原来是没了解WaitForSingleObject函数,非常感谢! 但还有一个问题,那互斥是不是应该是1,1信号量?WaitForSingleObject遇到初始值为0的信号量不阻塞吗?UNIX中的P操作-1 <0是阻塞啊...

呵呵,我说的0,1的意思是信号量的值的表示范围是[0,1],不是说初始化的时候为0
呵呵,非常感谢,我还有一个问题向讨教,有线程1,线程2,线程3三个线程,如果要求线程3在线程1和线程2都执行完之后才能执行,如何实现?我本来的想法是:
HANDLE hSemaphore;
hSemaphore = CreateSemaphore(NULL,-1,1,NULL);

线程1:
ReleaseSemaphore();
......

线程2:
ReleaseSemaphore();
......

线程3:
WaitForSingleObject(hSemaphore, INFINITE);
......
但是发现信号量的初始值不能设为-1......


信号量的初始值不能小于0
你的这个情况没必要用信号量,可以用事件的方式,理解上更清晰,非要用也可以:
HANDLE hSemaphore;
hSemaphore = CreateSemaphore(NULL,0,2,NULL);

线程1:
ReleaseSemaphore();
......

线程2:
ReleaseSemaphore();
......

线程3:
WaitForSingleObject(hSemaphore, INFINITE);
WaitForSingleObject(hSemaphore, INFINITE);// two times
......

建议你也可以参考下我的这个帖子:http://topic.csdn.net/u/20100308/16/7102875a-9103-494a-b1d0-253f1a1eba2e.html
houpk345 2010-03-09
  • 打赏
  • 举报
回复
引用 7 楼 wizardk 的回复:
引用 6 楼 houpk345 的回复:终于知道问题在哪里了,原来是没了解WaitForSingleObject函数,非常感谢! 但还有一个问题,那互斥是不是应该是1,1信号量?WaitForSingleObject遇到初始值为0的信号量不阻塞吗?UNIX中的P操作-1 <0是阻塞啊...

呵呵,我说的0,1的意思是信号量的值的表示范围是[0,1],不是说初始化的时候为0

呵呵,非常感谢,我还有一个问题向讨教,有线程1,线程2,线程3三个线程,如果要求线程3在线程1和线程2都执行完之后才能执行,如何实现?我本来的想法是:
HANDLE hSemaphore;
hSemaphore = CreateSemaphore(NULL,-1,1,NULL);

线程1:
ReleaseSemaphore();
......

线程2:
ReleaseSemaphore();
......

线程3:
WaitForSingleObject(hSemaphore, INFINITE);
......
但是发现信号量的初始值不能设为-1......
WizardK 2010-03-09
  • 打赏
  • 举报
回复
引用 6 楼 houpk345 的回复:
终于知道问题在哪里了,原来是没了解WaitForSingleObject函数,非常感谢!
但还有一个问题,那互斥是不是应该是1,1信号量?WaitForSingleObject遇到初始值为0的信号量不阻塞吗?UNIX中的P操作-1 <0是阻塞啊...


呵呵,我说的0,1的意思是信号量的值的表示范围是[0,1],不是说初始化的时候为0
houpk345 2010-03-09
  • 打赏
  • 举报
回复
终于知道问题在哪里了,原来是没了解WaitForSingleObject函数,非常感谢!
但还有一个问题,那互斥是不是应该是1,1信号量?WaitForSingleObject遇到初始值为0的信号量不阻塞吗?UNIX中的P操作-1<0是阻塞啊...
WizardK 2010-03-09
  • 打赏
  • 举报
回复
引用 4 楼 houpk345 的回复:
用事件实现互斥过程如下:
HANDLE hEvent;
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetEvent(hEvent);
线程一:
WaitForSingleObject(hEvent, INFINITE);
ResetEvent(hEvent);
....
SetEvent(hEvent);
线程二:
WaitForSingleObject(hEvent, INFINITE);
ResetEvent(hEvent);
....
SetEvent(hEvent);
但用信号量只有ReleaseSemaphore,岂不是类似于上面的只有ResetEvent而没有SetEvent,能举例说明吗?


首先,你的例子里面几个SetEvent和所有ResetEvent是多余的,用事件互斥是这样:
HANDLE hEvent;
hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
线程一:
WaitForSingleObject(hEvent, INFINITE);
....
SetEvent(hEvent);
线程二:
WaitForSingleObject(hEvent, INFINITE);
....
SetEvent(hEvent);

不知道这样写完之后,你能否将其和0,1信号量对应起来?
houpk345 2010-03-09
  • 打赏
  • 举报
回复
用事件实现互斥过程如下:
HANDLE hEvent;
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetEvent(hEvent);
线程一:
WaitForSingleObject(hEvent, INFINITE);
ResetEvent(hEvent);
....
SetEvent(hEvent);
线程二:
WaitForSingleObject(hEvent, INFINITE);
ResetEvent(hEvent);
....
SetEvent(hEvent);
但用信号量只有ReleaseSemaphore,岂不是类似于上面的只有ResetEvent而没有SetEvent,能举例说明吗?
WizardK 2010-03-09
  • 打赏
  • 举报
回复
引用 2 楼 houpk345 的回复:
引用 1 楼 wizardk 的回复:
UNIX的信号量和WINDOWS的信号量有本质上的区别吗?

如果你要互斥,就设置为0,1的信号量即可
那怎么实现减少信号量计数的值?


WaitForSingleObject
houpk345 2010-03-09
  • 打赏
  • 举报
回复
引用 1 楼 wizardk 的回复:
UNIX的信号量和WINDOWS的信号量有本质上的区别吗?

如果你要互斥,就设置为0,1的信号量即可

那怎么实现减少信号量计数的值?

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧