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多线程了