条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线承间的同步。
1.条件变量的结构为pthread_cond_t (相当于windows中的事件的作用)
2.条件变量的初始化
int pthread_cond_init __P ((pthread_cond_t *__cond,__const pthread_condattr_t *__cond_attr));
其中cond是一个指向结构pthread_cond_t的指针,cond_attr是一个指向结构pthread_condattr_t的指针。结构pthread_condattr_t是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用。注意初始化条件变量只有未被使用时才能重新初始化或被释放。
3.条件变量的释放
释放一个条件变量的函数为pthread_cond_ destroy(pthread_cond_t cond)
4.条件变量的等待
(1)函数pthread_cond_wait()使线程阻塞在一个条件变量上。它的函数原型为:
extern int pthread_cond_wait_P ((pthread_cond_t *__cond,pthread_mutex_t *__mutex));
线程解开mutex指向的锁并被条件变量cond阻塞。线程可以被函数pthread_cond_signal和函数pthread_cond_broadcast唤醒,但是要注意的是,条件变量只是起阻塞和唤醒线程的作用,具体的判断条件还需用户给出,例如一个变量是否为0等等,这一点我们从后面的例子中可以看到。线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。这个过程一般用while语句实现。
(2)另一个用来阻塞线程的函数是pthread_cond_timedwait(),它的原型为:
extern int pthread_cond_timedwait_P (pthread_cond_t *__cond,
pthread_mutex_t *__mutex, __const struct timespec
*__abstime);
它比函数pthread_cond_wait()多了一个时间参数,经历abstime段时间后,即使条件变量不满足,阻塞也被解除。
5.条件变量的解除改变
函数pthread_cond_signal()的原型为:
extern int pthread_cond_signal_P ((pthread_cond_t *__cond));
它用来释放被阻塞在条件变量cond上的一个线程。多个线程阻塞在此条件变量上时,哪一个线程被唤醒是由线程的调度策略 所决定的。要注意的是,必须用保护条件变量的互斥锁来保护这个函数,否则条件满足信号又可能在测试条件和调用pthread_cond_wait函数之间被发出,从而造成无限制的等待。
6.下面是使用函数pthread_cond_wait()和函数pthread_cond_signal()的一个简单的例子。
pthread_mutex_t count_lock;
pthread_cond_t count_nonzero;
unsigned count;
decrement_count () {
pthread_mutex_lock (&count_lock);
while(count==0)
pthread_cond_wait( &count_nonzero, &count_lock);
count=count -1;
pthread_mutex_unlock (&count_lock);
}
increment_count(){
pthread_mutex_lock(&count_lock);
if(count==0)
pthread_cond_signal(&count_nonzero);
count=count+1;
pthread_mutex_unlock(&count_lock);
}
count值为0时,decrement函数在pthread_cond_wait处被阻塞,并打开互斥锁count_lock。此时,当调用到函数increment_count时,pthread_cond_signal()函数改变条件变量,告知decrement_count()停止阻塞。
有的时候仅仅依靠锁住共享资源来使用它是不够的。有时候共享资源只有某些状态的时候才能够使用。比方说,某个线程如果要从堆栈中读取数据,那么如果栈中没有数据就必须等待数据被压栈。这种情况下的同步使用互斥锁
是不够
场景:女娲造人
抽象工厂模式
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类
场景问题解决类图:
主要涉及如下几个角色:
1.人种接口
2.白色人种
3.黄色人种
4.黑色人种
5.黄色女性人种、黑色女性人种、白色女性人种
6.黄色男性人种、黑色男性人种、白色男性人种
7.人种生成工厂接口
8.女性生成工厂
9.男性生成工厂
10.场景类
代码实现:
IHuman:
public interface Human { public void getColor(); public void talk(); public void getSex(); }
AbstractYellowHuman:
public abstract class AbstractYellowHuman implements Human{ public void talk() { } public void getColor() { } }
AbstractWhiteHuman:
public abstract class AbstractWhiteHuman implements Human { public void talk() { System.out.println("the white people speak english!"); } public void getColor() { System.out.println("the white people skin is white!"); } }
AbstractBlackHuman:
public abstract class AbstractBlackHuman implements Human { public void talk() { } public void getColor() { } }
FemalYellowHuman:
public class FemaleYellowHuman extends AbstractYellowHuman{ public void getSex() { } }
MaleYellowHuman:
public class MaleYellowHuman extends AbstractYellowHuman{ public void getSex() { // TODO Auto-generated method stub } }
HumanFactory:
public interface HumanFactory { public Human createYellowHuman(); public Human createBlackHuman(); public Human createWhiteHuman(); }
FemaleFactory:
public class FemaleFactory implements HumanFactory{ public Human createYellowHuman() { return new FemaleYellowHuman(); } public Human createBlackHuman() { return new FemaleBlackHuman(); } public Human createWhiteHuman() { return new FemaleWhiteHuman(); } }
MaleFactory:
public class MaleFactory implements HumanFactory{ public Human createYellowHuman() { return new MaleYellowHuman(); } public Human createBlackHuman() { return new MaleBlackHuman(); } public Human createWhiteHuman() { return new MaleWhiteHuman(); } }
Client:
public class NvWa { public static void main(String[] agrs) throws Exception { HumanFactory maleHumanFactory = new MaleFactory(); HumanFactory femaleHumanFactory = new FemaleFactory(); Human maleYellowHuman = maleHumanFactory.createYellowHuman(); Human femaleYelloHuman = femaleHumanFactory.createYellowHuman(); maleYellowHuman.getColor(); maleYellowHuman.talk(); maleYellowHuman.getSex(); femaleYelloHuman.getColor(); femaleYelloHuman.talk(); femaleYelloHuman.getSex(); } }
主要特点:
高度脚本
十六进制编辑器
IO包裹
文件系统支持
调试器支持
进行比较的两个功能或二进制文件之间
操作码,代码分析basicblock
它包含了系列工具,如反汇编工具、调试工具和16进制编辑工具。
支持新的命令(ad, pm, wa*, dm*, dh, pdb, ia, /q, ax, dd, and /d),支持Brainfuck,hex:// and http:// r_io 插件,支持rap://的元数据。
radare2是一款用于创建一个完整、便携式和多架构的逆向工程的工具链。它是由一个十六进制编辑器组成,支持本地/远程文件的多个后端
层,调试器(OS X操作系统,BSD,LINUX,W32),stream分析仪,适用于x86、ARM、PPC、m68k、Java、MSIL和SPARC的汇编/反汇编程序,
代码分析模块,和脚本设施功能。它也有一个bindiffer命名为radiff,base转换器(RAX),RASC,二进制信息的提取,支持PE,Mach0,
ELF,类,等等,命名为rabin,可运行于 Linux、Windows、Maemo、iTouch/iPhone 等多种平台。
命令:
$ strings -el -t x hackgyver.exe
$ radiff2 -C crackme0x07 crackme0x08
$ r2 ./crackme0x07
aa
$ rabin2 -I crackme0x07
$ export LOLO= && echo "6640" | ./crackme0x07
$ rasm2 -b 64 -s intel -f shell64.exe
$ rasc2 -s
"b8a08888fa05777777074831ff0f05b88b8888fa05777777070f05b8198a88fa05777777074831d24831f60f05b8c48888fa057777770748bf2f62696e
2f2f736856574889e70f05" -X