如何不使用pthread cond t 使用

pid_t 是哪一种数据类型,pthread_t是哪一种数据类型,如何打印不产生警告?
引用地址:
注意: 该地址仅在今日23:59:59之前有效
一)进程ID:pid_t 是那一种数据类型:是Linux下的进程号类型,也就是Process ID _ Type 的缩写。 其实是宏定义的unsigned int类型,warning: format ‘%u’ expects type ‘unsigned int’, but argument 2 has type ‘pthread_t’:使用%lu打印pthread_t不会出现警告。二)线程ID:编译时如果使用%x打印pthread_t会出现警告信息:thread-pool.c:77: warning: format ‘%x’ expects type ‘unsigned int’, but argument 3 has type ‘pthread_t’如果使用%lu打印pthread_t不会出现警告。如:问题一,对宏定义的返回数据类型作出一个定义,如下面是对进程数作定义:
#define PROCESS_NUM 1 //进程数
#define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
/* 父进程信号处理 */
void kill_signal_master(const int sig) {
&&&&//这儿得是long unsigned类型,否则会警告:warning: comparison between signed and unsigned integer expressions
&&&& /* 删除PID文件 */
&&&& remove(httpmut_settings_pidfile);//删除掉pid文件
&&&& //kill(0, SIGTERM);//这个是一个进程情况
&&&& /* 给进程组发送SIGTERM信号,结束子进程 */
&&&& for (i=0; i&GET_ARRAY_LEN(processArr); i++) {//批量杀死所有子进程&&
&&&&&&&& kill(processArr[i], SIGTERM);&&
&&&& }&&
&&&& exit(0);
问题二:对pid_t进程号用printf打印出现警告:pid_pthread_printf(&\nthread id is %lu,procees id is %lu,waiting for into while...\n&,t,p); format ‘%lu’ expects type ‘long unsigned int’, but argument 3 has type ‘pid_t’&&这PID pthread_t打印用啥格式?: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘pid_t’: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’如果打印pid_t这种类型,你知道它是整数,但是不知道具体类型,而且在不同平台也可能不同一般做法是强转下:&%lld&, (long long)xxx或者&%llu&, (unsigned long long)xxx因为C的整数最大就是long long实践Ok代码如下:
//获得进程id
p = getpid();
//获得线程id
t=pthread_self();
printf(&\nthread id is %lld,procees id is %lld,waiting for into while...\n&,(long long)t,(long long)p);
printf(&\n进入线程:看是不是不同的线程来干活?thread id is %lld,procees id is %lld,waiting for into while...\n&,(long long)t,(long long)p);&&
作者:@地址:版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
最后编辑: justwinit 编辑于 10:55
[9/9]北京市海淀区中关村理想国际大厦18层 Address:Sina 18th floor Ideal plaza Zhongguancun Haidain
Beijing 100080, P.R.China
[1/9]深圳南山腾讯大厦8楼 Address:Tencent Plaza High-tech One Road, Middle Zone, High-new Science & Technology Park, Nanshan Distrcit, Shenzhen City, Guangdong Province 518057, P.R. China
[2/9]深圳南山腾讯大厦旁大族激光大厦三楼 Address:Han's Building,Kejizhongyi Avenue, Hi-tech Pack,Nanshan District, Shenzhen City, Guangdong Province 518057, P.R.China
[2012/10-Now]北京海淀区西三环中路10号望海楼B座7层央视国际网络有限公司 Address:Seaview floor, Haidian District No.10,West Sanhuan Road,Beijing 100142, P.R.China正确使用pthread_create,防止内存泄漏 - DoubleLi - 博客园
近日,听说pthread_create会造成内存泄漏,觉得不可思议,因此对posix(nptl)的线程创建和销毁进行了分析。
分析结果:如果使用不当,确实会造成内存泄漏。
产生根源:pthread_create默认创建的线程是非detached的。
预防方式:要么创建detached的线程,要么线程线程的start_routine结束之前detached,要么join
分析过程如下:
& 1.查看pthread_create源代码,核心代码如下(nptl/pthread_create.c):
__pthread_create_2_1&(newthread,&attr,&start_routine,&arg)
&&&&&pthread_t&*
&&&&&const&pthread_attr_t&*
&&&&&void&*(*start_routine)&(void&*);&
&&&&&void&*
&&STACK_VARIABLES;
&&const&struct pthread_attr&*iattr&=&(struct pthread_attr&*)&
&&if&(iattr&==&NULL)
&&&&/*&Is&this the best idea?&On&NUMA machines this could mean
&&&&&&&accessing far-away memory.&*/
&&&&iattr&=&&default_
&&struct pthread&*pd&=&NULL;
&&int err = ALLOCATE_STACK (iattr, &pd);//为tcb分配内存
&&if&(__builtin_expect&(err&!=&0,&0))&
&&&&/*&Something went wrong.&Maybe a parameter of the attributes&is
&&&&&&&invalid&or&we could&not&allocate memory.&*/
&&&&return&
err = create_thread (pd, iattr, STACK_VARIABLES_ARGS);//正式创建线程
2.查看createthread.c(nptl/sysdeps/pthread/createthread.c)
static&int&
create_thread&(struct pthread&*pd,&const&struct pthread_attr&*attr,
&&&&&&&&&&&STACK_VARIABLES_PARMS)
#ifdef TLS_TCB_AT_TP
&&assert&(pd-&header.tcb&!=&NULL);
int res = do_clone (pd, attr, clone_flags,&start_thread,
& & & & & & & & & STACK_VARIABLES_ARGS, 1);//clone一个进程
3.接着看start_thread(nptl/pthread_create.c)做了什么
static&int
start_thread&(void&*arg)
&&struct pthread&*pd&=&(struct pthread&*)&
&&&&&&/*&Run the code the user provided.&*/
#ifdef CALL_THREAD_FCT
&&&&&&THREAD_SETMEM&(pd,&result,&CALL_THREAD_FCT&(pd));&
&&&&&&THREAD_SETMEM (pd, result, pd-&start_routine (pd-&arg));&//正式启动线程的执行,并等待执行完成
if (IS_DETACHED (pd))
& & /* Free the TCB. &*/
& & __free_tcb (pd);//如果设置detached标志,则释放tcb占用的内容,否则直接返回
& else if (__builtin_expect (pd-&cancelhandling & SETXID_BITMASK, 0))
& & & /* Some other thread might call any of the setXid functions and expect
& & &us to reply. &In this case wait until we did that. &*/
& & lll_futex_wait (&pd-&setxid_futex, 0, LLL_PRIVATE);
& & & while (pd-&cancelhandling & SETXID_BITMASK);
& & & /* Reset the value so that the stack can be reused. &*/
& & & pd-&setxid_futex = 0;
从上面的过程,我们可以看到,如果在创建线程的时候,如果没有设置detached标志,则tcb内存永远不会释放
接下来,我们看看pthread_detach(npth/pthread_detach.c)做了什么
pthread_detach&(th)
&&&&&pthread_&
&&struct pthread&*pd&=&(struct pthread&*)&&
&&/*&Make sure the descriptor&is&valid.&*/
&&if&(INVALID_NOT_TERMINATED_TD_P&(pd))
&&&&/*&Not&a valid thread handle.&*/
&&&&return ESRCH;
&&int&result&=&0;
&&/*&Mark the thread as detached.&*/
&&if&(atomic_compare_and_exchange_bool_acq&(&pd-&joinid,&pd,&NULL))
&&&&&&/*&There are two possibilities here.&First,&the thread might
&&&&&already be detached.&In&this&case&we return EINVAL.
&&&&&Otherwise there might already be a waiter.&The standard does
&&&&&not&mention what happens&in&this&case.&*/
&&&&&&if&(IS_DETACHED&(pd))
&&&&result&=&EINVAL;
&&&&/*&Check whether the thread terminated meanwhile.&In&this&case&we
&&&&&&&will just free the TCB.&*/
&&&&if&((pd-&cancelhandling&&&EXITING_BITMASK)&!=&0)
&&&&&&/*&Note that the code&in&__free_tcb makes sure&each&thread
&&&&&control block&is&freed only once.&*/
&&&&&&__free_tcb (pd);//经过一系列的容错判断,直接释放tcb占用的内存
最后,我们看一下pthread_join(nptl/pthread_join.c)做了什么
pthread_join&(threadid,&thread_return)
&&&&&pthread_
&&&&&void&**thread_
&&struct pthread&*pd&=&(struct pthread&*)&
&&/*&Make sure the descriptor&is&valid.&*/
&&if&(INVALID_NOT_TERMINATED_TD_P&(pd))
&&&&/*&Not&a valid thread handle.&*/
&&&&return ESRCH;
&&/*&Is&the thread joinable?.&*/
&&if&(IS_DETACHED&(pd))
&&&&/*&We cannot wait&for&the thread.&*/
&&&&return EINVAL;
&&struct pthread&*self&=&THREAD_SELF;
&&int&result&=&0;
&&/*&During the wait we change&to&asynchronous cancellation.&If&we
&&&&&are canceled the thread we are waiting&for&must be marked as
&&&&&un-wait-ed&for&again.&*/
&&pthread_cleanup_push&(cleanup,&&pd-&joinid);
&&/*&Switch&to&asynchronous cancellation.&*/
&&int&oldtype&=&CANCEL_ASYNC&();
&&if&((pd&==&self
&&&&&&&||&(self-&joinid&==&pd
&&&&&&&&(pd-&cancelhandling
&&&&&&&(CANCELING_BITMASK&|&CANCELED_BITMASK&|&EXITING_BITMASK
&&&&&&&&&|&TERMINATED_BITMASK))&==&0))
&&&&&&&&&!CANCEL_ENABLED_AND_CANCELED&(self-&cancelhandling))
&&&&/*&This&is&a deadlock situation.&The threads are waiting&for&each
&&&&&&&other&to&finish.&Note that this&is&a&"may"&error.&To&be 100%
&&&&&&&sure we catch this&error&we would have&to&lock the data
&&&&&&&structures but it&is&not&necessary.&In&the unlikely&case&that
&&&&&&&two threads are really caught&in&this situation they will
&&&&&&&deadlock.&It&is&the programmer's problem&to&figure this
&&&&&&&out.&*/
&&&&result&=&EDEADLK;
&&/*&Wait&for&the thread&to&finish.&If&it&is&already locked something
&&&&&is&wrong.&There can only be one waiter.&*/
&&else&if&(__builtin_expect&(atomic_compare_and_exchange_bool_acq&(&pd-&joinid,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& self,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&NULL),&0))
&&&&/*&There&is&already somebody waiting&for&the thread.&*/
&&&&result&=&EINVAL;
&&&&/*&Wait&for&the child.&*/
&&&&lll_wait_tid&(pd-&tid);
&&/*&Restore cancellation mode.&*/
&&CANCEL_RESET&(oldtype);
&&/*&Remove the handler.&*/
&&pthread_cleanup_pop&(0);
&&if&(__builtin_expect&(result&==&0,&1))
&&&&&&/*&We mark the thread as terminated&and&as joined.&*/
&&&&&&pd-&tid&=&-1;
&&&&&&/*&Store the return value&if&the caller&is&interested.&*/
&&&&&&if (thread_return != NULL)
&&&&*thread_return = pd-&//设置返回值
&&&&&&/* Free the TCB. */
&&&&&&__free_tcb (pd);/释放TCB占用内存
综上,如果要保证创建线程之后,确保无内存泄漏,必须采用如下方法来规范pthread_create的使用:
方法一、创建detached的线程
void run()&{&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
int&main(){&
&&&&pthread_&
&&&&pthread_attr_&
&&&&pthread_attr_init(&&attr&);&
&&&&pthread_attr_setdetachstate(&attr,1);&
&&&&pthread_create(&thread,&&attr,&run,&0);&
& & & & &&
&&&&//......&
&&&&return 0;&
方法二、要么线程线程的start_routine结束之前detached
void run()&{&
&&&&pthread_detach(pthread_self());&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
int&main(){&
&&&&pthread_&&
&&&&pthread_create(&thread,&NULL,&run,&0);&
& & & & & & &&
&&&&//......&
&&&&return 0;&
方法三、主线程使用pthread_join
void run()&{&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
int&main(){&
&&&&pthread_&
&&&&pthread_create(&thread,&NULL,&run,&0);&&
& & & & & & & & & & & & & & & & & & & &
&&&&//......&
& & pthread_join(thread,NULL);
&&&&return 0;&2013年10月 Linux/Unix社区大版内专家分月排行榜第二2013年9月 Linux/Unix社区大版内专家分月排行榜第二
2013年12月 Linux/Unix社区大版内专家分月排行榜第三2013年11月 Linux/Unix社区大版内专家分月排行榜第三2013年6月 Linux/Unix社区大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年3月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。Linux 下使用 pthread 库开发多线程学习 | 科技爱好者博客
3 weeks, 4 days ago
3 months ago
3 months ago
4 months ago
4 months ago
- 8,997 views - 5,748 views - 3,146 views - 1,808 views - 1,661 views - 1,655 views - 1,581 views - 1,444 views - 1,418 views - 1,303 views
热评文章文章归档C语言使用pthread多线程编程(windows系统)二 - jack_Meng - 博客园
随笔 - 631, 文章 - 1, 评论 - 75, 引用 - 0
我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我的程序是在Linux下写的,所以我使用了Pthread库(是不是很伤心,我知道有不少人期待的是WindowsAPI的,好吧,有机会以后再讲那个,现在先把这一系列专题写完&^_^)如果你用的是LINUX/UNIX/MacOSX,那么我们已经可以开始了,如果你用的是WINDOWS,那么你需要从网站上下载PTHREAD的WINDOWS开发包,所幸他非常的小。网站地址是http://sourceware.org/pthreads-win32/先来看一个基本的例子:&程序代码#include&&pthread.h&#include&&iostream&using&namespace&void*&tprocess1(void*&args){&&&&&&&&&while(1){&&&&&&&&&&&&&&&&&cout&&&&"tprocess1"&&&&&&&&&&&&&}&&&&&&&&&return&NULL;}void*&tprocess2(void*&args){&&&&&&&&&while(1){&&&&&&&&&&&&&&&&&cout&&&&"tprocess2"&&&&&&&&&&&&&}&&&&&&&&&return&NULL;}int&main(){&&&&&&&&&pthread_t&t1;&&&&&&&&&pthread_t&t2;&&&&&&&&&pthread_create(&t1,NULL,tprocess1,NULL);&&&&&&&&&pthread_create(&t2,NULL,tprocess2,NULL);&&&&&&&&&pthread_join(t1,NULL);&&&&&&&&&return&0;}在上面的例子中,我们首先加入了pthread.h文件包含,这是所以pthread多线程程序所必须的,接着是iostream我们进行输入输出时要用到,接着就是两个函数的定义,这和普通的函数没有什么区别,之所以写成的&程序代码void*&tprocess1(void*&args)这样的形式,完全是为了迎合pthread_create函数的参数类型,你也可以不这样定义,只要在调用pthread_create创建线程的时候强制转换一下指针类型就可以了。这两个函数将被用做线程的执行体,也就是说在两个线程里同时运行这两个函数。现在我们来看main函数,和pthread有关的调用都在这里了。pthread_t是线程结构,用来保存线程相关数据,你也可以理解为是线程类型,声明一个线程对象(变量)。&程序代码&&&&&&&&&pthread_t&t1;&&&&&&&&&pthread_t&t2;这里我们声明了两个线程变量t1,t2&程序代码&&&&&&&&&pthread_create(&t1,NULL,tprocess1,NULL);&&&&&&&&&pthread_create(&t2,NULL,tprocess2,NULL);这两句非常重要,pthread_create用来创建线程并启动,他的原型是&程序代码int&pthread_create(pthread_t&*&thread,&pthread_attr_t&*&attr,&void&*&(*start_routine)(void&*),&void&*&arg);我们可以知道第一个参数是线程指针,第二参数是线程属性指针,线程属性pthread_attr_t用来指定线程优先级等属性,一般的情况下,我们没有必要修改,使用默认属性来构造线程,所以这里一般取NULL,我们也是这样做的,第三个参数是一个函数指针(函数指针?什么东西,没听说过啊?&&巨晕,好嘛,你复习一下C或是C++指针那部分吧)就是线程要执行的代码,这里我们分别要执行tprocess1&tprocess2就写成了上面的样子,这里这个函数指针的类型定义是返回一个空类型指针,接收一个空类型指针参数的函数指针,如果你的函数不是这个定义,那就可以直接转化一下就可以了。写完这两行代码,两个线程就已经执行起来了,但是如果你省略了&程序代码&&&&&&&&&pthread_join(t1,NULL);然后尝试编译运行程序的时候你会发现程序似乎什么也没干就退出了,是的,那是因为程序的主线程退出的时候操作系统会关闭应用程序使用的所有资源,包括线程&&所以在main函数结束前我们得想办法让程序停下来,pthread_join方法的功能就是等待线程结束,要等的线程就是第一个参数,程序会在这个地方停下来,直到线程结束,第二个参数用来接受线程函数的返回值,是void**类型的指针,如果没有返回值,就直接设为NULL吧。程序写好了,我们怎么编译运行它呢?如果你使用的是Linux:在终端里输入g++&thread.cpp&-othread&-lpthread./thread就可以完成程序的编译及运行如果你用的是VC:在工程属性里加入开发包里的几个库文件把那几个DLL文件放到你的工程路径里,也就是程序运行时候的工作路径,这个在VC6和2005里似乎不太一样,如果你不确定,那就直接放到SYSTEM32里吧。。。下面的工作就非常简单了点运行,提示编译,就确定,好了,结果出来了。。。是不是感觉多线程如此的简单,短短几行代码就搞定了,我想你已经可以写出一个简单的多线程程序了吧,呵呵,其实问题没有这么简单,多线程我们还要面对线程同步的问题,我会在下一个专题里给大家讲到。&&
出处:/lovko/archive//1376032.html

我要回帖

更多关于 pthread mutex t 使用 的文章

 

随机推荐