threading.Thread

Pool

lock,condition.event

#!/usr/bin/env python3
# thread.py
# -*- coding: utf-8 -*-

__author__ = 'bravo'

import os,time, random
from multiprocessing import Process
from multiprocessing import Pool
import threading
import os


lock = threading.Lock()

def subproc(name):
    start = time.time();
    print('%s Child(%d) created' % (name,os.getpid()))
    time.sleep(random.random()*3)
    end = time.time()
    print('%s Child(%d) lasts %02f times' % (name,os.getpid(),end-start))


def fork_test():
    print('start')
    pid = os.fork()
    if(pid == 0):
        print('child ', os.getpid(),'with parenet',os.getppid())
    elif (pid > 0):
        print('parent')
    else:
        print('error')


def pool_test():
    print(threading.current_thread().name)
    print('Parent(%d)' % os.getpid())
    p = Pool(1000)
    for i in range(1000):
        p.apply_async(subproc,(i,))
    p.close()
    p.join()
    print('All done')

def thread_test():
    t = threading.Thread(target=pool_test,name='thread for pool')
    t.start()
    t.join()


ev = threading.Event()

def gogogo(item):
    index,ev = item
    if index != 9:
        print('wait',index)
        ev.wait()
    else:
        print('set')
        ev.set()
    time.sleep(index)
    print('item',index)

def start_thread(obj):
        print(obj.isalive())
        return

if __name__ == '__main__':
    # thread prepare 注意参数如何传递的,线程函数不能用用*arg **kwds来作参数
    thread_l = [threading.Thread(target = gogogo,args = ([i,ev],)) \
     for i in range(10)]

    # lambda同时启动, map后得到的是iterator,需要list下才真正执行
    list(map(lambda obj:obj.join(),thread_l))
    #fork_test()
    #poll_test()
    # thread_test()
    input('end')

Read More

场景 1 虚拟继承

#include <iostream>
class A {static int s;};
class B: virtual public A {};
class C: virtual public A {};
class D: public B, public C{char a;};
int main(int argc , char* argv[])
{

	std::cout << "A: " << sizeof(A) << std::endl;
	std::cout << "B: " << sizeof(B) << std::endl;
	std::cout << "C: " << sizeof(C) << std::endl;
	std::cout << "D: " << sizeof(D) << std::endl;
	return 0;
}

ubuntu 64bits g++ 5.4.0 结果:

A: 1 // static变量不占object的内存!
B: 8
C: 8
D: 24 //8 + 8 + 1 + 7

A: 编译器插入 1 字节,表明 object 的唯一地址用的;

B:C 加上 vptr,但是又不需要那 1 字节了?

D: 继承 ,两个 vptr !(virtual public 不起作用?)

结论: 编译器行为…很不好说.可能自己插入一些字节, 另外还有可能有需要补齐也占用 object 的字节.

data member 的布局

class E {
	public:
		virtual ~E(){}
		int a;
		char b;
		void * c;
		virtual void foo() {}

};

E e;
std::cout << "E: " << sizeof(E) << std::endl;
std::cout << "e.addr " << &e << std::endl;
std::cout << "e.a " << &(e.a) << std::endl;
std::cout << "e.b " << &(e.b) << std::endl;
std::cout << "e.c " << &(e.c) << std::endl;

结果是:

E: 24 = 8 +4 + 1 + 3 + 8
e.addr 0x7ffd47bb2c50
e.a 0x7ffd47bb2c58
e.b
e.c 0x7ffd47bb2c60

E 的大小为 size(vptr) + size(int) + size(char) + size(void*)=24.

但有的编译器, 不一定把 vptr 放在开头的位置.也可能放在结尾, a,b,c 这些 data member 的顺序也可能在任意位置.

继承类的 data member 的布局

  • 一般来说就是 base class data member + derived class new data member.但是 data member 的布局也不是确定的,仍然取决于编译器.

  • 多重继承,可能带来多重 padding,(如派生每次都多出一个 char 变量,需要补齐为 4),造成空间的浪费.

  • 如果 base class 没有 vitural function ,而 drived class 有:

Base b;
Derived d &  = b;

编译器得在编译器介入,为 d 插入 vptr.

  • 多重继承
#include <iostream>

class A {int m_a; char m_ca;};
class B {int m_b;};
class C :public A, public B { int m_c;};

int main(int argc , char* argv[])
{
	A a;
	B b;
	C c;

	A* pa = &c;
	B* pb = &c;
	std::cout << "c addr: " << &c << std::endl;
	std::cout << "pa addr: " << pa << std::endl;
	// pb =  (B*)(&c + sizeof(A))
	std::cout << "pb addr: " << pb << std::endl;
	return 0;
}

Read More