免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8946 | 回复: 10
打印 上一主题 下一主题

请教:线程互斥锁问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-09 12:04 |只看该作者 |倒序浏览
#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mutex;

void*
thread(void *arg)
{
        while(1) {
                pthread_mutex_lock(&mutex);
                printf("pthread:%d\n", (int)arg);
                sleep(2);
                pthread_mutex_unlock(&mutex);
        }
        pthread_exit(NULL);

}
int
main(void)
{
        int             i;
        pthread_t     pid[10];

      
        pthread_mutex_init(&mutex, NULL);
        for (i = 0; i < 10; i++) {
                pthread_create( pid + i, NULL, thread, (void*)i);
        }
        while(1)
        ;
        return 0;
}


输出:
pthread:0
pthread:0
pthread:0
pthread:0
pthread:0
pthread:0
pthread:0
pthread:0
pthread:0
     .
     .
     .
为什么不是这样:
pthread:0
pthread:1
pthread:2
pthread:3
pthread:4
pthread:5
pthread:6
pthread:7
pthread:8

是不是因为系统调度的时候不考虑互斥锁,也就是互斥锁没有等待队列
只要线程在运行,并且没有其他线程正在占用互斥锁,就可以得到锁,不考虑互斥的先后

有没有介绍多线程锁方面的资料,谢谢共享一下

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2007-05-09 12:57 |只看该作者
关键的问题是,在多个线程争用(都试图锁住)同一个锁的时候,当这个锁被 unlock,那么哪个线程可以获取(lock)该锁?

论坛徽章:
0
3 [报告]
发表于 2007-05-09 13:03 |只看该作者
原帖由 tourer 于 2007-5-9 12:04 发表
#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mutex;

void*
thread(void *arg)
{
        while(1) {
                pthread_mutex_lock(&mutex);
                p ...


建议你看一下"高级GNU/Linux编程"那本书

我有一篇blog文章也是介绍这个方面的内容的,你可以看一下:
http://blog.chinaunix.net/u1/35100/showart_274716.html

论坛徽章:
0
4 [报告]
发表于 2007-05-10 10:08 |只看该作者

  1. void*
  2. thread(void *arg)
  3. {
  4.         while(1) {
  5.                 pthread_mutex_lock(&mutex);
  6.                 printf("pthread:%d\n", (int)arg);
  7.                 sleep(2);
  8.                 pthread_mutex_unlock(&mutex);
  9.         }
  10.         pthread_exit(NULL);

  11. }
复制代码

说说我的看法:
线程0虽然在锁住锁2秒后释放了锁,但是它在释放后马上又去尝试锁住这个锁,而且成功了
   如果pthread_mutex_lock是阻塞方式的话,按理说在线程0释放锁之后线程i(i>0)也会知道锁可用这个消息的,但是这中间是需要时间的,试猜想阻塞的解除是采用信号的方式来处理的,当线程0释放锁后,系统向其他线程发送一个消息,告诉它们可以去锁住锁了,但是这个时候线程0却并不需要接收并处理信号这个过程,它不需等待直接就可占用锁资源了,理论上它再次获取锁的速度胜于其他线程;其次,如果阻塞的解除是采用轮询方式的话,就更容易理解了,当其他线程查询锁的使用情况的时刻还未到来的时候,线程0就已经释放锁,并且再次占用了锁。
上面只是本人自己的一点理解,对OS具体的实现还不清楚,也许是采用等待队列之类的其他机制实现。等等
我想,如果改成

  1. void*
  2. thread(void *arg)
  3. {
  4.         while(1) {
  5.                 pthread_mutex_lock(&mutex);
  6.                 printf("pthread:%d\n", (int)arg);
  7.                 sleep(2);
  8.                 pthread_mutex_unlock(&mutex);
  9.                 sleep(2);//或者sleep(rand()%10);
  10.         }
  11.         pthread_exit(NULL);
  12. }
复制代码

我想这样的话效果可能就不一样了吧

[ 本帖最后由 duanjigang 于 2007-5-10 10:10 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2007-05-10 10:43 |只看该作者
在不同的系统上得到的结果应该不同。check the multithread shedule policy for detail information.
在sun上应该是一直得到 0,在windows上应该是0~9.

论坛徽章:
0
6 [报告]
发表于 2007-05-10 13:20 |只看该作者
duanjigang 说得很对,当你释放掉锁得时候,马上又循环到加锁,这时其他的线程还在等待锁得释放,但它们却没有机会了。
  所以其实只要你在释放锁后,再给其他线程得到锁得机会(时间 象下面那样也是可以的,其实和duanjigang 写的差不多),那么其他线程就能够得到锁了。但这里存在着一个竞争机制,可能各个系统实现不一样,到底是那个线程先得到这个锁呢?


  1. void*
  2.       7 thread(void *arg)
  3.       8 {
  4.       9     while(1)
  5.      10     {
  6.      11         pthread_mutex_lock(&mutex);
  7.      12         printf("pthread:%d\n", (int)arg);
  8.      14         pthread_mutex_unlock(&mutex);
  9.      15         sleep(2);
  10.      16     }
  11.      17     pthread_exit(NULL);
  12.      18 }

  13.    
复制代码

论坛徽章:
0
7 [报告]
发表于 2007-05-10 13:23 |只看该作者
原帖由 tourer 于 2007-5-9 12:04 发表
#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mutex;

void*
thread(void *arg)
{
        while(1) {
                pthread_mutex_lock(&mutex);
                p ...


看错了

论坛徽章:
0
8 [报告]
发表于 2007-05-10 22:49 |只看该作者
man sched_yield

论坛徽章:
0
9 [报告]
发表于 2008-05-26 12:02 |只看该作者
多谢分享。

最近正好遇到这样一个问题。已经解决:)

论坛徽章:
0
10 [报告]
发表于 2008-05-26 20:13 |只看该作者
跟pthread和调度策略的实现有关
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP