apue读书笔记-第十一章

1,为什么程序11-1的输出与书上不同?

      在我的机器上:

  

new:  pid 3558 tid 3067210560 0xb6d1eb40
new:  pid 3558 tid 3058817856 0xb651db40
new:  pid 3558 tid 3075603264 0xb751fb40
main:  pid 3558 tid 3075606208 0xb75206c0
new:  pid 3558 tid 3050425152 0xb5d1cb40

    可以看出pid是一样的,也就是说是一个进程,而且tid实际上是指针,书上讲的是以前的LinuxThreads实现,现在linux使用NPTL线程

    关于这两个线程实现可以参考:http://www.ibm.com/developerworks/cn/linux/l-threading.html

2,跟进程类似,返回码只能获取一次,对同一线程再次调用pthread_join会失败,它们甚至不会阻塞,同一时间对一个线程只能有一个jion掉用,其它的将直接失败

3,pthread_cleanup_push和pthread_cleanup_pop为什么要成对使用?

     因为它们是宏实现的,直观的说,两边一起用才能凑齐一对大括号

     从代码可以看到,这两个宏的实现在c和c++里面是不一样的

4,条件变量有什么用?

     避免等待线程轮训某个条件变量,改而使用类似信号机制的方法

5,在多核处理器下,由于内部实现,pthread_cond_signal可能唤醒多个线程

    

#include"../apue.h"
pthread_t ntid;
pthread_t ntid1;

pthread_mutex_t mut;
pthread_cond_t prdy;

char g_s[4]="123";
int g_n=0;

vector<int> queue;
void foo1()
{
    
}
void* thFun(void* arg)
{
    printtID("new: ");
    while(1)
    {
        pthread_mutex_lock(&mut);
        printf("lock %u\n",(uint)pthread_self());
        while(queue.size()==0)
        {
            pthread_cond_wait(&prdy,&mut);    
            printf("cond wait %u %d\n",(uint)pthread_self(),queue.size());        
        }
        queue.pop_back();
        pthread_mutex_unlock(&mut);
        
    }
     
    return (void*)0;
}
int main()
{
    pthread_mutex_init(&mut,NULL);
    pthread_cond_init(&prdy,NULL);
    int err=pthread_create(&ntid,NULL,thFun,NULL);
    err=pthread_create(&ntid1,NULL,thFun,NULL);
    err=pthread_create(&ntid1,NULL,thFun,NULL);
    err=pthread_create(&ntid1,NULL,thFun,NULL);
    printtID("main: ");
    while(1)
    {
        pthread_mutex_lock(&mut);
        queue.push_back(1234);
        pthread_mutex_unlock(&mut);
        getchar();
        pthread_cond_signal(&prdy);
         
    }    
     
    

    sleep(100);    
    return 1;
}

很坑爹,我的机器上输出如下:

new:  pid 3084 tid 3066198848 0xb6c27b40
lock 3066198848
main:  pid 3084 tid 3074598656 0xb742a700
new:  pid 3084 tid 3057806144 0xb6426b40
lock 3057806144
new:  pid 3084 tid 3049413440 0xb5c25b40
new:  pid 3084 tid 3074591552 0xb7428b40
lock 3057806144
lock 3049413440
lock 3074591552
a
cond wait 3066198848 2
lock 3066198848
lock 3066198848
cond wait 3057806144 0

它其实唤醒了两个线程

查阅man pthread_cond_signal:

Multiple Awakenings by Condition Signal
       On a multi-processor, it may be impossible  for  an  implementation  of
       pthread_cond_signal()  to  avoid the unblocking of more than one thread
       blocked on a condition variable. For example,  consider  the  following
       partial  implementation  of  pthread_cond_wait()  and pthread_cond_sig‐
       nal(), executed by two threads in the order given. One thread is trying
       to  wait  on  the condition variable, another is concurrently executing
       pthread_cond_signal(), while a third thread is already waiting.

 

习题11.2

    没看明白,要改job里面的id的话,把id也锁起来不就好了?要改动的的时候获取写锁不就行了吗?

    这跟remove有什么关系呢?

习题11.3 

    为什么会有惊群效应?

    如果需要不同的线程来处理不同的工作,要么每一种工作使用一种条件变量,要么使用一个条件变量,唤醒所有的等待线程,后者会引起大量的等待线程被唤醒,会降低效率

    如果任意线程都能处理任意job,那么每次只需要唤醒一个,也就没有惊群效果了

习题11.4

   这道题让我很迷惑,下面是我的理解

   调用broadcast后,每个等待线程都会被唤醒,它们将依次获得互斥量,然后进行处理

   前一种方法,每个等待线程都会被唤醒

   后一种方法,在第三步和第四步中间给了此时已经被唤醒的线程执行的机会(如果job来得很快就有这种可能),如果此时job被分配,那么第四步就不用去唤醒n多线程了

 

  

转载于:https://www.cnblogs.com/mightofcode/archive/2013/01/12/2847964.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值