Linux多线程编程的基本的函数.docx

上传人:b****2 文档编号:2555475 上传时间:2023-05-04 格式:DOCX 页数:19 大小:18.11KB
下载 相关 举报
Linux多线程编程的基本的函数.docx_第1页
第1页 / 共19页
Linux多线程编程的基本的函数.docx_第2页
第2页 / 共19页
Linux多线程编程的基本的函数.docx_第3页
第3页 / 共19页
Linux多线程编程的基本的函数.docx_第4页
第4页 / 共19页
Linux多线程编程的基本的函数.docx_第5页
第5页 / 共19页
Linux多线程编程的基本的函数.docx_第6页
第6页 / 共19页
Linux多线程编程的基本的函数.docx_第7页
第7页 / 共19页
Linux多线程编程的基本的函数.docx_第8页
第8页 / 共19页
Linux多线程编程的基本的函数.docx_第9页
第9页 / 共19页
Linux多线程编程的基本的函数.docx_第10页
第10页 / 共19页
Linux多线程编程的基本的函数.docx_第11页
第11页 / 共19页
Linux多线程编程的基本的函数.docx_第12页
第12页 / 共19页
Linux多线程编程的基本的函数.docx_第13页
第13页 / 共19页
Linux多线程编程的基本的函数.docx_第14页
第14页 / 共19页
Linux多线程编程的基本的函数.docx_第15页
第15页 / 共19页
Linux多线程编程的基本的函数.docx_第16页
第16页 / 共19页
Linux多线程编程的基本的函数.docx_第17页
第17页 / 共19页
Linux多线程编程的基本的函数.docx_第18页
第18页 / 共19页
Linux多线程编程的基本的函数.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Linux多线程编程的基本的函数.docx

《Linux多线程编程的基本的函数.docx》由会员分享,可在线阅读,更多相关《Linux多线程编程的基本的函数.docx(19页珍藏版)》请在冰点文库上搜索。

Linux多线程编程的基本的函数.docx

Linux多线程编程的基本的函数

Linux多线程编程的基本的函数

1线程创建

函数原型:

#include

intpthread_create(pthread_t*restricttidp,constpthread_attr_t*restrict

attr,void*(*start_rtn)(void),void*restrictarg);

返回值:

若是成功建立线程返回0,否则返回错误的编号

形式参数:

pthread_t*restricttidp要创建的线程的线程id指针

constpthread_attr_t*restrictattr创建线程时的线程属性

void*(start_rtn)(void)返回值是void类型的指针函数

vodi*restrictargstart_rtn的行参

例题1:

功能:

测试建立一个新的线程

程序名称:

pthread_test.c

#include

#include

void*create(void*arg)

...{

printf("newthreadcreated.....");

}

intmain(intargc,char*argv[])

...{

pthread_ttidp;

interror;

error=pthread_create(&tidp,NULL,create,NULL);

if(error!

=0)

......{

printf("pthread_createisnotcreated...");

return-1;

}

printf("prthread_createiscreated...");

return0;

}

编译方法:

#gcc-Wall-lpthreadpthread_test.c

因为pthread的库不是linux系统的库,所以在进行编译的时候要加上-lpthread,否则编译不过,会出现下面错误

thread_test.c:

在函数‘create’中:

thread_test.c:

7:

警告:

在有返回值的函数中,程序流程到达函数尾

/tmp/ccOBJmuD.o:

Infunction

'main':

thread_test.c:

(.text+0x4f):

对‘pthread_create’未定义的引用

collect2:

ld返回1

现在我们能建立了一个线程了,我们可以从函数的原型看到,在创建线程的时候,是可以在对我们的函数进行传递参数,在pthread_create的第四个行参。

我们看一下例题2~3.

例题2

功能:

向新的线程传递整形值

程序名称:

pthread_int.c

#include

#include

#include

void*create(void*arg)

...{

int*num;

num=(int*)arg;

printf("createparameteris%d",*num);

return(void*)0;

}

intmain(intargc,char*argv[])

...{

pthread_ttidp;

interror;

inttest=4;

int*attr=&test;

error=pthread_create(&tidp,NULL,create,(void*)attr);

if(error!

=0)

...{

printf("pthread_createiscreatedisnotcreated...");

return-1;

}

sleep

(1);

printf("pthread_createiscreatediscreated...");

return0;

}

编译方法:

gcc-lpthreadthread_int.c-Wall

执行结果:

createparameteris4

pthread_createiscreatediscreated...

例题总结:

可以看出来,我们在main函数中传递的整行指针,传递到我们新建的线程函数中。

在上面的例子可以看出来我们向新的线程传入了另一个线程的int数据,线程之间还可以传递字符串或是更复杂的数据结构。

例题3:

程序功能:

向新建的线程传递字符串

程序名称:

thread_char.c

#include

#include

#include

void*create(void*arg)

...{

char*name;

name=(char*)arg;

printf("argis%s",name);

return(void*)0;

}

intmain(intargc,char*argv[])

...{

char*a="wang";

interror;

pthread_ttidp;

error=pthread_create(&tidp,NULL,create,(void*)a);

if(error!

=0)

...{

printf("pthreadisnotcreated");

return-1;

}

sleep

(1);

printf("pthreadiscreated...");

return0;

}

编译方法:

gcc-Wallthread_char.c-lpthread

执行结果:

argiswang

pthreadiscreated...

例题总结:

可以看出来main函数中的字符串传入了新建里的线程中。

例题4

程序名称:

thread_struct.c

#include

#include

#include

#include/**//*malloc()*/

structtest

...{

inta;

char*s;

};

void*create(void*arg)

...{

structtest*temp;

temp=(structtest*)arg;

printf("test->a==%d",temp->a);

printf("test->s==%s",temp->s);

return(void*)0;

}

intmain(intargc,char*argv[])

...{

pthread_ttidp;

interror;

structtest*b;

b=(structtest*)malloc(sizeof(structtest));

b->a=4;

b->s="wang";

error=pthread_create(&tidp,NULL,create,(void*)b);

if(error!

=0)

...{

printf("phreadisnotcreated...");

return-1;

}

sleep

(1);

printf("pthreadiscreated...");

return0;

}

编译方法:

gcc-Wall-lpthreadthread_struct.c

执行结果:

test->a==4

test->s==wang

pthreadiscreated...

线程包含了标识进程内执行环境必须的信息。

他集成了进程中的所有信息都是对线程进行共享的,包括文本程序、程序的全局内存和堆内存、栈以及文件描述符。

例题5

程序目的:

验证新建立的线程可以共享进程中的数据

程序名称:

thread_share.c

#include

#include

#include

staticinta=4;

void*create(void*arg)

...{

printf("newpthread...");

printf("a==%d",a);

return(void*)0;

}

intmain(intargc,char*argv[])

...{

pthread_ttidp;

interror;

a=5;

error=pthread_create(&tidp,NULL,create,NULL);

if(error!

=0)

...{

printf("newthreadisnotcreate...");

return-1;

}

sleep

(1);

printf("newthreadiscreated...");

return0;

}

编译方法:

gcc-Wall-lpthreadthread_share.c

执行结果:

newpthread...

a==5

newthreadiscreated...

例题总结:

可以看出来,我们在主线程更改了我们的全局变量a的值的时候,我们新建立的线程则打印出来了改变的值,可以看出可以访问线程所在进程中的数据信息。

2、线程的终止

如果进程中任何一个线程中调用exit,_Exit,或者是_exit,那么整个进程就会终止,与此类似,如果信号的默认的动作是终止进程,那么,把该信号发送到线程会终止进程。

线程的正常退出的方式:

(1)线程只是从启动例程中返回,返回值是线程中的退出码

(2)线程可以被另一个进程进行终止

(3)线程自己调用pthread_exit函数

两个重要的函数原型:

#include

voidpthread_exit(void*rval_ptr);

/*rval_ptr线程退出返回的指针*/

intpthread_join(pthread_tthread,void**rval_ptr);

/*成功结束进程为0,否则为错误编码*/

例题6

程序目的:

线程正常退出,接受线程退出的返回码

程序名称:

exit_return.c

#include

#include

#include

void*create(void*arg)

...{

printf("newthreadiscreated...");

return(void*)2;

}

intmain(intargc,char*argv[])

...{

pthread_ttid;

interror;

void*temp;

error=pthread_create(&tid,NULL,create,NULL);

if(error!

=0)

...{

printf("threadisnotcreated...");

return-1;

}

error=pthread_join(tid,&temp);

if(error!

=0)

...{

printf("threadisnotexit...");

return-2;

}

printf("threadisexitcode%d",(int)temp);

sleep

(1);

printf("threadiscreated...");

return0;

}

编译方法:

gcc-Wallexit_return.c-lpthread

执行结果:

newthreadiscreated...

threadisexitcode2

threadiscreated...

线程退出不仅仅可以返回线程的int数值,还可以返回一个复杂的数据结构

例题7

程序目的:

线程结束返回一个复杂的数据结构

程序名称:

exit_thread.c

#include

#include

#include

structtest

...{

inta;

char*b;

};

structtesttemp=

...{

.a=4,

.b="wang"

};

void*create(void*arg)

...{

printf("newthread...");

return(void*)&temp;

}

intmain(intargc,char*argv[])

...{

interror;

pthread_ttid;

structtest*c;

error=pthread_create(&tid,NULL,create,NULL);

if(error!

=0)

...{

printf("newthreadisnotcreated...");

return-1;

}

printf("main...");

error=pthread_join(tid,(void*)&c);

if(error!

=0)

...{

printf("newthreadisnotexit...");

return-2;

}

printf("c->a==%d",c->a);

printf("c->b==%s",c->b);

sleep

(1);

return0;

}

编译方法:

gcc-Wall-lpthreadexit_struct.c

执行结果:

main...

newthread...

c->a==4

c->b==wang

例题总结:

一定要记得返回的数据结构要是在这个数据要返回的结构没有释放的时候应用,如果数据结构已经发生变化,那返回的就不会是我们所需要的,而是藏数据阿。

3、线程标识

函数原型:

#include

pthread_tpthread_self(void);

例题8

程序目的:

实现在新建立的线程中打印该线程的id和进程id

程序名称:

thread_self.c

#include

#include

#include/**//*getpid()*/

void*create(void*arg)

...{

printf("newthread....");

printf("thread_tid==%u",(unsignedint)pthread_self());

printf("threadpidis%d",getpid());

return(void*)0;

}

intmain(intargc,char*argv[])

...{

pthread_ttid;

interror;

printf("Mainthreadisstarting...");

error=pthread_create(&tid,NULL,create,NULL);

if(error!

=0)

...{

printf("threadisnotcreated...");

return-1;

}

printf("mainpidis%d",getpid());

sleep

(1);

return0;

}

编译方法:

gcc-Wall-lpthreadthread_self.c

执行结果:

Mainthreadisstarting...

mainpidis6860

newthread....

thread_tid==3084954544

threadpidis6860

4、线程的处理程序

函数原型:

#include

voidpthread_cleanup_push(void(*rtn)(void*),void*arg);

函数rtn是清理函数,arg是调用参数

voidpthread_cleanup_pop(intexecute);

在前面讲过线程的终止方式,是正常终止还是非正常终止,都会存在一个资源释放的问题,在posix中提供了一组,就是我们上面看的函数进行线程退出的处理函数,有些像在进程中的atexit函数。

释放的方式是指pthread_cleanup_push的调用点到pthread_cleanup_pop之间程序段进行终止。

pthread_cleanup_push()/pthread_cleanup_pop采用先入后出的方式的栈的管理方式,void*rtn(void

*),在执行pthread_cleanup_push()时压入函数栈,多次执行pthread_cleanup_push()形成一个函数链,在执行这个函数链的时候会以反方向弹出,即先入后出。

execute参数表识,是否执行弹出清理函数,当execute=0时不进行弹出清理函数,非零的时候弹出处理函数。

例题9

程序目的:

实现在正常结束线程的时候,进行函数处理

程序名称:

thread_clean.c

编译方法:

执行结果:

thread1start

thread1pushcomplete

thread1exitcode1

thread2start

thread2pushcomplete

cleanup:

thread2secondhandler

cleanup:

thread2firsthandler

thread2exitcode2

gcc-Wall-lpthreadthread_clean.c

#include

#include

#include

void*clean(void*arg)

...{

printf("cleanup:

%s",(char*)arg);

return(void*)0;

}

void*thr_fn1(void*arg)

...{

printf("thread1start");

pthread_cleanup_push(clean,"thread1firsthandler");

pthread_cleanup_push(clean,"thread1secondhadler");

printf("thread1pushcomplete");

if(arg)

...{

return((void*)1);

}

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

return(void*)1;

}

void*thr_fn2(void*arg)

...{

printf("thread2start");

pthread_cleanup_push(clean,"thread2firsthandler");

pthread_cleanup_push(clean,"thread2secondhandler");

printf("thread2pushcomplete");

if(arg)

...{

pthread_exit((void*)2);

}

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

pthread_exit((void*)2);

}

intmain(void)

...{

interr;

pthread_ttid1,tid2;

void*tret;

err=pthread_create(&tid1,NULL,thr_fn1,(void*)1);

if(err!

=0)

...{

printf("error....");

return-1;

}

err=pthread_create(&tid2,NULL,thr_fn2,(void*)1);

if(err!

=0)

...{

printf("error....");

return-1;

}

err=pthread_join(tid1,&tret);

if(err!

=0)

...{

printf("error....");

return-1;

}

printf("thread1exitcode%d",(int)tret);

err=pthread_join(tid2,&tret);

if(err!

=0)

...{

printf("error....");

return-1;

}gcc-Wall-lpthreadthread_clean.c

printf("thread2exitcode%d",(int)tret);

exit(0);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2