3 4 #include <pthread.h> 5 using namespace std; 6 7 void *pth(void *v){ 8 int *p; 9 p = (int*)v; 10 int i = 10 * (*p); 11 char *pp; 12 pp = new char [i]; 13 14 15 sleep(2); 16 delete [] pp; 17 cout <<"delete success"<<endl; 18 return 0; 19 } 20 21 int main(){ 22 pthread_t pts[10]; 23 int i; 24 for(i = 1;i < 10;i ++){ 25 pthread_create(&pts[i],0,pth,(void*)&i); 26 } 27 for(int i = 1;i < 10;i ++){ 28 // pthread_join(pts[i],0); 29 }
两个问题请教大家
第一,为什么会分配18块内存
第二,如果调用28行,则释放18块,如果不调用,则只是释放9块
线程同步没做好,传给子线程的是i的地址,但是子线程创建以后不可能立刻运行,这样在子线程中int i = 10 * (*p); i的值就是不确定的,所以分配的内存必然也就不固定了!
同样的道理,当子线程运行完后会释放内存,而去掉28行以后,也就去掉了线程同步,能完整运行完的子线程也是不确定的,能释放的内存也就不确定了,当然最后内存都会被系统回收。
从上面的分析可以得知,这里的18和9,也是不一定的,看下图
你是说i导致的分配块数的问题
pthread_join导致的释放块数的问题对吗
我看了一下,是不是线程切换导致的分配18块,
子线程正在分配内存的过程中,切换到了父线程,此时父线程也注意到要分配内存,然后也分配内存了。
最后导致分配了18块
释放的时候因为子线程后推出,父线程先退出,所以看到的只是父线程释放了18块
@demps_c:不是不是,导致这个问题的原因是父子线程同步问题,因为你的父线程在创建了子线程以后,子线程还不一定立刻运行,正如我的截图,在系统压力比较小的时候,父线程会一下子把是个线程都创建完!而你传给子线程的是i的地址值,这样当子线程运行的时候,它读取的参数值就是不确定的,在我的系统中是先创建了10个子线程,接着子线程运行,这时候所有十个子线程的参数i的值是10!
这些都是由于你的程序没有线程同步而导致的!
搞不懂的是在我电脑上面如果不调用pthread_join或者父线程sleep(结果是父线程比子线程后退出),就会出现释放的内存总是比申请的内存块数少5
@飞鸿眉敛: 少9,申请块数不定,
@demps_c: 进程退出条件其中有两条
1 最后一个线程从其启动例程返回
2 最后一个线程调用pthread_exit
写给自己
@demps_c: 这些问题归根结底都是线程同步的问题,你把线程同步做了,这些就不是问题了!
你可以在创建子线程的之前new一个int,然后传给子线程,子线程释放这个int对象。这样:
for(i = 1;i < 10;i ++) {
int *p = new int;
*p = i;
pthread_create(&pts[i],0,pth,(void*)p);
}
这么做,子线程获得的值就会是1--9;
不过为什么少9块,我还确实不知道……但我有一个猜想,因为我不是很熟悉linux,也就不好测试,只好我说出来你去试试!
你看你的i是从1开始到9,也就是创建了9个子线程,而线程都会返回一个值,这个值由pthread_join函数的第二个指针引出,所以我在猜想,你的子线程函数return 0时,系统会不会malloc了一个int,这样9个线程刚好9块内存,你可以如下试试:
for(int i = 1;i < 10;i ++){
int *status;
pthread_join(pts[i],&status);
free(status);
}
@飞鸿眉敛: 非常感谢,谢谢了
@demps_c: 要结帖啊啊啊啊啊,^_^
@飞鸿眉敛: 你是在哪工作,怎么一直都在线
@demps_c: 在上海工作,暂时事不是很多,小公司