pthread key create_create未定义问题

linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。
#include &pthread.h&
int pthread_create(pthread_t *restrict tidp,
const pthread_attr_t *restrict attr,
void *(*start_rtn)(void),
void *restrict arg);
Returns: 0 if OK, error number on failure
C99 中新增加了 restrict 修饰的指针: 由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。 由 restrict 修饰的指针主要用于函数形参,或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。
下面这个程序中,我们的函数thr_fn不 需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。当创建线程成功时,函数返回0,若不为0则说明创建线程 失败,常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。 创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。
#include&stdio.h&
#include&pthread.h&
#include&string.h&
#include&sys/types.h&
#include&unistd.h&
pthread_t ntid;
void printids(const
pid_t pid;
pthread_t tid;
= getpid();
= pthread_self();
printf(&%s pid %u tid %u (0x%x)\n&,s,(unsigned
int)pid,(unsigned
int)tid,(unsigned
void *thr_fn(void
printids(&new thread:&);
int main(){
= pthread_create(&ntid,NULL,thr_fn,NULL);
printf(&can't create thread: %s\n&,strerror(err));
printids(&main thread:&);
把APUE2上的一个程序修改一下,然后编译。
pthread.c:(.text+0x85):对‘pthread_create’未定义的引用
由于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时,在编译中要加-lpthread参数:
gcc -o pthread -lpthread pthread.c
这是一个关于Posix线程编程的专栏。作者在阐明概念的基础上,将向您详细讲述Posix线程库API。本文是第一篇将向您讲述线程的创建与取消。
1.1 线程与进程
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。在串行程序基础上引入线程和进程是为了提高程序的并发度,从而提高程序运行效率和响应时间。
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。
1.2 创建线程
POSIX通过pthread_create()函数创建线程,API定义如下:
int&& pthread_create(pthread_t&& *&& thread, pthread_attr_t * attr,
void * (*start_routine)(void *), void * arg)
与fork()调用创建一个进程的方法不同,pthread_create()创建的线程并不具备与主线程(即调用 pthread_create()的线程)同样的执行序列,而是使其运行start_routine(arg)函数。thread返回创建的线程ID,而 attr是创建线程时设置的线程属性(见下)。pthread_create()的返回值表示线程创建是否成功。尽管arg是void *类型的变量,但它同样可以作为任意类型的参数传给start_routine()函数;同时,start_routine()可以返回一个void
*类型的返回值,而这个返回值也可以是其他类型,并由pthread_join()获取。
1.3 线程创建属性
pthread_create()中的attr参数是一个结构指针,结构中的元素分别对应着新线程的运行属性,主要包括以下几项:
__detachstate,表示新线程是否与进程中其他线程脱离同步,如果置位则新线程不能用pthread_join()来同步,且在退出时自 行释放所占用的资源。缺省为PTHREAD_CREATE_JOINABLE状态。这个属性也可以在线程创建并运行以后用 pthread_detach()来设置,而一旦设置为PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置)则不能再恢复 到 PTHREAD_CREATE_JOINABLE状态。
__schedpolicy,表示新线程的调度策略,主要包括SCHED_OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和 SCHED_FIFO(实时、先入先出)三种,缺省为SCHED_OTHER,后两种调度策略仅对超级用户有效。运行时可以用过 pthread_setschedparam()来改变。
__schedparam,一个struct sched_param结构,目前仅有一个sched_priority整型变量表示线程的运行优先级。这个参数仅当调度策略为实时(即SCHED_RR 或SCHED_FIFO)时才有效,并可以在运行时通过pthread_setschedparam()函数来改变,缺省为0。
__inheritsched,有两种值可供选择:PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED, 前者表示新线程使用显式指定调度策略和调度参数(即attr中的值),而后者表示继承调用者线程的值。缺省为 PTHREAD_EXPLICIT_SCHED。
__scope,表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。POSIX的标准中定义了两个值: PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同 进程中的线程竞争CPU。目前LinuxThreads仅实现了PTHREAD_SCOPE_SYSTEM一值。
pthread_attr_t结构中还有一些值,但不使用pthread_create()来设置。
为了设置这些属性,POSIX定义了一系列属性设置函数,包括pthread_attr_init()、pthread_attr_destroy()和与各个属性相关的pthread_attr_get---/pthread_attr_set---函数。
1.4 线程创建的Linux实现
我们知道,Linux的线程实现是在核外进行的,核内提供的是创建进程的接口do_fork()。内核提供了两个系统调用__clone()和fork (),最终都用不同的参数调用do_fork()核内API。当然,要想实现线程,没有核心对多进程(其实是轻量级进程)共享数据段的支持是不行的,因 此,do_fork()提供了很多参数,包括CLONE_VM(共享内存空间)、CLONE_FS(共享文件系统信息)、CLONE_FILES(共享文 件描述符表)、CLONE_SIGHAND(共享信号句柄表)和CLONE_PID(共享进程ID,仅对核内进程,即0号进程有效)。当使用fork系统
调用时,内核调用do_fork()不使用任何共享属性,进程拥有独立的运行环境,而使用pthread_create()来创建线程时,则最终设置了所 有这些属性来调用__clone(),而这些参数又全部传给核内的do_fork(),从而创建的&进程&拥有共享的运行环境,只有栈是独立的,由 __clone()传入。
Linux线程在核内是以轻量级进程的形式存在的,拥有独立的进程表项,而所有的创建、同步、删除等操作都在核外pthread库中进行。 pthread 库使用一个管理线程(__pthread_manager(),每个进程独立且唯一)来管理线程的创建和终止,为线程分配线程ID,发送线程相关的信号 (比如Cancel),而主线程(pthread_create())的调用者则通过管道将请求信息传给管理线程。
2.1 线程取消的定义
一般情况下,线程在其主体函数退出的时候会自动终止,但同时也可以因为接收到另一个线程发来的终止(取消)请求而强制终止。
2.2 线程取消的语义
线程取消的方法是向目标线程发Cancel信号,但如何处理Cancel信号则由目标线程自己决定,或者忽略、或者立即终止、或者继续运行至Cancelation-point(取消点),由不同的Cancelation状态决定。
线程接收到CANCEL信号的缺省处理(即pthread_create()创建线程的缺省状态)是继续运行至取消点,也就是说设置一个CANCELED状态,线程继续运行,只有运行至Cancelation-point的时候才会退出。
2.3 取消点
根据POSIX标准,pthread_join()、pthread_testcancel()、pthread_cond_wait()、 pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及read()、write()等会引起阻塞的系 统调用都是Cancelation-point,而其他pthread函数都不会引起Cancelation动作。但是pthread_cancel的手 册页声称,由于LinuxThread库与C库结合得不好,因而目前C库函数都不是Cancelation-point;但CANCEL信号会使线程从阻
塞的系统调用中退出,并置EINTR错误码,因此可以在需要作为Cancelation-point的系统调用前后调用 pthread_testcancel(),从而达到POSIX标准所要求的目标,即如下代码段:
pthread_testcancel();
&&&& retcode = read(fd, buffer, length);
&&&& pthread_testcancel();
2.4 程序设计方面的考虑
如果线程处于无限循环中,且循环体内没有执行至取消点的必然路径,则线程无法由外部其他线程的取消请求而终止。因此在这样的循环体的必经路径上应该加入pthread_testcancel()调用。
2.5 与线程取消相关的pthread函数
int pthread_cancel(pthread_t thread)
发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。
int pthread_setcancelstate(int state, int *oldstate)
设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和 PTHREAD_CANCEL_DISABLE,分别表示收到信号后设为CANCLED状态和忽略CANCEL信号继续运行;old_state如果不为 NULL则存入原来的Cancel状态以便恢复。
int pthread_setcanceltype(int type, int *oldtype)
设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和 PTHREAD_CANCEL_ASYCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到信号后继续运行至下一个取消点再退出和 立即执行取消动作(退出);oldtype如果不为NULL则存入运来的取消动作类型值。
void pthread_testcancel(void)
检查本线程是否处于Canceld状态,如果是,则进行取消动作,否则直接返回。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:81363次
积分:1048
积分:1048
排名:第17855名
转载:97篇
评论:18条
(1)(1)(2)(1)(1)(2)(5)(2)(1)(3)(3)(3)(1)(2)(8)(1)(11)(10)(6)(5)(19)(14)3029人阅读
linux 下c语言编程
线程 POSIX线程库
编译时出现错误
对‘pthread_create’未定义的引用 对‘pthread_join’未定义的引用
-------------------------------
Eclipse&+ CDT:
pthread_create函数编译时报错:undefined reference to `pthread_create’
undefined reference to `pthread_create’
undefined reference to `MD5′
由于pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,在编译中要加 -lpthread参数。
例如:在加了头文件#include 之后执行 pthread.c文件,需要使用如下命令:
gcc thread.c -o thread -lpthread
这种情况类似于
的使用,需在编译时加 -m 参数。
+++++++++
Linux上编译pthread程序,默认会出错。如题。原因如下。
Add support for multithreading using the POSIX threads library.
This option sets flags for both the preprocessor and linker. It
does not affect the thread safety of object code produced by the
compiler or that of libraries supplied with it. These are HP-UX
specific flags.
所以如果在gcc的编译中(更准确的说是链接中)没有启动pthread的话,就会出现如下的链接错误。
pthread_test.c:(.text+0x8a): undefined reference to `pthread_create’
collect2: ld returned 1 exit status
另外一个参数-lpthread也能起到同样的作用。所以可以看出-pthread的本质应当时引入了thread对应的library。默认情况下,pthread对应的library在gcc编译链接中是不会被引入的。
所以 gcc -o backupfile backupfiles.c -pthread
出现如下错误:
undefined reference to ‘pthread_create’
undefined reference to ‘pthread_join’
问题原因:
pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。
问题解决:
在编译中要加 -lpthread参数
gcc thread.c -o thread -lpthread
thread.c为你些的源文件,不要忘了加上头文件#include
+++++++++
解决方法如下:
Project-&Properties-&C/C++ Build-&Settings-&GCC C++ Linker-&Libraries
在Libraries(-l)中添加pthread即可
在Libraries search path(-L)中添加crypto即可
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:308731次
积分:5723
积分:5723
排名:第1410名
原创:68篇
转载:1293篇
评论:30条
(72)(70)(60)(88)(67)(14)(10)(69)(75)(84)(11)(9)(45)(91)(41)(120)(153)(180)(101)(3)新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
空间积分0 信誉积分2091 UID阅读权限20积分598帖子精华可用积分622 专家积分0 在线时间1898 小时注册时间最后登录
丰衣足食, 积分 598, 距离下一级还需 402 积分
帖子主题精华可用积分622 专家积分0 在线时间1898 小时注册时间最后登录
论坛徽章:0
本帖最后由 yshihyu 于
02:25 编辑
我下载后编译 make , 产生 libmindroid.so
之后我想测试 tests 里面的 HelloWorld.cpp
g++ -lpthread -o test HelloWorld.cpp ./libmindroid.so
./libmindroid.so: 未定义的参考到“sem_init”
./libmindroid.so: 未定义的参考到“pthread_key_create”
./libmindroid.so: 未定义的参考到“pthread_once”
./libmindroid.so: 未定义的参考到“sem_destroy”
./libmindroid.so: 未定义的参考到“pthread_getspecific”
./libmindroid.so: 未定义的参考到“pthread_mutex_timedlock”
./libmindroid.so: 未定义的参考到“sem_timedwait”
./libmindroid.so: 未定义的参考到“pthread_create”
./libmindroid.so: 未定义的参考到“sem_post”
./libmindroid.so: 未定义的参考到“pthread_condattr_setclock”
./libmindroid.so: 未定义的参考到“pthread_setspecific”
./libmindroid.so: 未定义的参考到“sem_wait”
./libmindroid.so: 未定义的参考到“pthread_join”
collect2: error: ld returned 1 exit status
请问这是什么原因?
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
空间积分0 信誉积分1008 UID阅读权限20积分572帖子精华可用积分572 专家积分0 在线时间838 小时注册时间最后登录
丰衣足食, 积分 572, 距离下一级还需 428 积分
帖子主题精华可用积分572 专家积分0 在线时间838 小时注册时间最后登录
论坛徽章:1
这发帖时间。。。。。。。。
空间积分0 信誉积分2270 UID阅读权限50积分2846帖子精华可用积分2848 专家积分0 在线时间5361 小时注册时间最后登录
小富即安, 积分 2846, 距离下一级还需 2154 积分
帖子主题精华可用积分2848 专家积分0 在线时间5361 小时注册时间最后登录
论坛徽章:8
把-l参数放到前面是很多人常犯的错误。应该放到自己的文件后面,互相有依赖的按照顺序,被依赖的放在右边。
空间积分0 信誉积分2530 UID9731032阅读权限90积分22251帖子精华可用积分22251 专家积分10 在线时间2496 小时注册时间最后登录
巨富豪门, 积分 22251, 距离下一级还需 17749 积分
帖子主题精华可用积分22251 专家积分10 在线时间2496 小时注册时间最后登录
论坛徽章:77
-lpthread放到最后
最困难的事就是人的事了
空间积分0 信誉积分2243 UID阅读权限100积分136848帖子精华可用积分136848 专家积分55 在线时间4509 小时注册时间最后登录
帖子主题精华可用积分136848 专家积分55 在线时间4509 小时注册时间最后登录
论坛徽章:8
& & 不要用 -lpthread,直接用 -pthread
I can explain it for you, but I can’t understand it for you.
空间积分0 信誉积分2091 UID阅读权限20积分598帖子精华可用积分622 专家积分0 在线时间1898 小时注册时间最后登录
丰衣足食, 积分 598, 距离下一级还需 402 积分
帖子主题精华可用积分622 专家积分0 在线时间1898 小时注册时间最后登录
论坛徽章:0
本帖最后由 yshihyu 于
20:24 编辑
zhaohongjian000 发表于
把-l参数放到前面是很多人常犯的错误。应该放到自己的文件后面,互相有依赖的按照顺序,被依赖的放在右边。
________________________________________________________________________________________________
g++ -o test HelloWorld.cpp ./libmindroid.so&&-lpthread
g++ -o test HelloWorld.cpp&&-lpthread ./libmindroid.so
请问这样序顺那个才是正确?
空间积分0 信誉积分2270 UID阅读权限50积分2846帖子精华可用积分2848 专家积分0 在线时间5361 小时注册时间最后登录
小富即安, 积分 2846, 距离下一级还需 2154 积分
帖子主题精华可用积分2848 专家积分0 在线时间5361 小时注册时间最后登录
论坛徽章:8
& &&&g++ -o test HelloWorld.cpp ./libmindroid.so&&-lpthread
另外5楼说的是对的,对于pthread库,应该用-pthread替代-lpthread。
空间积分0 信誉积分2091 UID阅读权限20积分598帖子精华可用积分622 专家积分0 在线时间1898 小时注册时间最后登录
丰衣足食, 积分 598, 距离下一级还需 402 积分
帖子主题精华可用积分622 专家积分0 在线时间1898 小时注册时间最后登录
论坛徽章:0
ok...thanks注册时间 13:08:35
最后登录 12:11:10
用户头衔:注册会员
状态:我不在线
这是APUE 上的一个关于pthread的程序.可是我编译时gcc提示
phtread_create 未定义,可是pthread.h加了的吗!?也有 /usr/include/pthread.h 这个头文件!请路过的朋友能看看呀!3q!
#include &pthread.h&
#include &stdlib.h&
#include &stdio.h&
#include &unistd.h&
pthread_
static void printids(char *);
static void *thr_fn(void *);
int
main(void)
{
err = pthread_create (&ntid, NULL,thr_fn, NULL);
if (err != 0)
printf ("ptherd_create error \n");
printids ("main thread: ");
sleep (1);
exit (0);
}
void printids(char *s)
{
pid = getpid ();
tid = pthread_self ();
printf ("%s pid %u
(0x%x)\n",
s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);
}
void *thr_fn(void *arg)
{
printids ("new thread: ");
return ((void *)0);
}
注册时间 23:33:02
最后登录 16:41:12
用户头衔:注册会员
状态:我不在线
-..- .---- .----
Processed in : 0.010000 second(s) (C)2014LinuxSir -}

我要回帖

更多关于 pthread key create 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信