分类: C/C++
2007-06-07 21:44:44
Linuxcici Phread
本文档为个人学习线程笔记. 不断更新以方便日后复习
文章内容部分选自网络,部分为自己概括.
编译命令类似于:gcc -o echo1 echo.c -lpthread
条件变量只是起阻塞和唤醒线程的作用
===================================================
web资源(线程):
http://blog.sina.com.cn/s/blog_4956c756010008p0.html
http://i.mop.com/mxpopstar/blog/2007/09/21/4865964.html
===================================================
************* pthread_create **************
int pthread_create(pthread_t *tid, const pthread_attr_t *tattr, void *(*start_routine)(void *), void *arg);
返回值:函数成功返回0。任何其他返回值都表示错误。创建一个线程参数tattr中含有初始化线程所需要的属性,
start_routine是线程入口函数的地址,当start_routine返回时,相应的线程就结束了。当函数成功时,线程标
示符保存在参数tid指向的内存中。
[默认线程是可汇合]
e.g:
#include
#include
void handle(void)
{
int i;
for( i=0; i < 10; i++)
{
printf("my name is sub_thread.\n");
}
}
int main(void){
pthread_t id; /*定义线程描述符号*/
int i ;
int ret;
ret = pthread_create(&id,NULL,(void *) handle,NULL); /*创建一个线程*/
if(ret != 0)
{
printf ("Create pthread error!\n");
exit (1);
}
for(i=0 ; i < 10 ; i++)
{
printf("my name is main_thread.\n");
}
pthread_join(id,NULL); /*主线程等待之线程结束*/
return (0);
}
每次运行的结果可能不同
****************************************************
************* pthread_once **************
仅执行一次的操作
int pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进
程执行序列中仅执行一次。once_run()函数仅执行一次,且究竟在哪个线程中执行是不定的
尽管pthread_once(&once,once_run)出现在两个线程中。
#include
#include
pthread_once_t once=PTHREAD_ONCE_INIT;
void once_run(void)
{
printf("once_run in thread %d\n",pthread_self());
}
void * child1(void *arg)
{
int tid=pthread_self();
printf("thread %d enter\n",tid);
pthread_once(&once,once_run);
printf("thread %d returns\n",tid);
}
void * child2(void *arg)
{
int tid=pthread_self();
printf("thread %d enter\n",tid);
pthread_once(&once,once_run);
printf("thread %d returns\n",tid);
}
int main(void)
{
int tid1,tid2;
printf("hello\n");
pthread_create(&tid1,NULL,child1,NULL);
pthread_create(&tid2,NULL,child2,NULL);
sleep(10);
printf("main thread exit\n");
return 0;
}
[root@localhost 06]# ./pthread3
hello
thread 3086535584 enter
once_run in thread 3086535584
thread 3086535584 return
thread 3076045728 enter
thread 3076045728 return
main thread exit
LinuxThreads使用互斥锁和条件变量保证由pthread_once()指定的函数执行且仅执行一次,而once_control则表征是否执行过。如果
once_control的初值不是PTHREAD_ONCE_INIT(LinuxThreads定义为0),pthread_once()的行为就会不正常。在LinuxThreads中,实际"一次性
函数"的执行状态有三种:NEVER(0)、IN_PROGRESS(1)、DONE(2),如果once初值设为1,则由于所有pthread_once()都必须等待其中一个
激发"已执行一次"信号,因此所有pthread_once()都会陷入永久的等待中;如果设为2,则表示该函数已执行过一次,从而所有pthread_once()
都会立即返回0。
****************************************************
在pthread_create()中的attr中detchstate可以设置线程属性
(PTHREAD_CREATE_JOINABLE)
可汇合线程: 终止后还会保留某些分配给它的资源,直到其它线程使用phread_join调用后才能再次分配这些资源.
(PTHREAD_CREATE_DETACHED)
脱离线程:终止时释放该线程的所有资源.其它线程不能用pthread_join来与它的终止进行同步
只要设成了(PTHREAD_CREATE_DETACHED)状态就不能恢复到(PTHREAD_CREATE_JOINABLE)状态
****************************************************
************* pthread_detach **************
分离线程pthread_detach
#include
int pthread_detach(pthread_t tid);
返回值:函数成功返回0。任何其他返回值都表示错误。
将线程设置为脱离线程。即通知线程库在指定的线程终止时回收线程占用的内存等资源。
在一个线程上使用多次pthread_detach的结果是不可预见的。
****************************************************
************* pthread_join **************
待线程结束pthread_join
int pthread_join(pthread_t tid, void **status);
返回值:函数成功返回0。任何其他返回值都表示错误。
等待一个线程结束。
调用pthread_join的线程将被挂起.直到参数tid指定的线程结束。
tid指定的线程必须在当前进程中,同时tid指定的线程必须是汇合的。
不能有多个线程等待同一个线程终止。如果出现这种情况,一个线程将成功返回,别的线程将返回错误ESRCH。
如果参数status不为NULL,则将线程的退出状态放在status指向的内存中。
(用于存放线程所等待的返回值)
/* example.c*/
#include
#include
void thread(void)
{
int i;
for(i=0;i<3;i++)
printf("This is a pthread.\n");
}
int main(void)
{
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,(void *) thread,NULL);
if(ret!=0){
printf ("Create pthread error!\n");
exit (1);
}
for(i=0;i<3;i++)
printf("This is the main process.\n");
pthread_join(id,NULL);
return (0);
}
我们编译此程序:
gcc example1.c -lpthread -o example1
int pthread_exit(void *retval)
如果pthread_join()第二个参数不是NULL,那么值就传给status.
e.g:
/*pthread_join的status用于存放等待线程的返回值
主要用于看看返回值的测试结果*/
#ifdef __Linux__
# define _REENTRANT
# define _POSIX_SOURCE
#endif
/* Hack for LinuxThreads */
#ifdef __Linux__
# define _P __P%3