注意线程相关函数返回值:0-表示成功,>0-表示错误代码。
线程的创建
int
pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void
*(*start)(void *), void *arg)
注意点:
- pthread_t, pthread_attr_t等变量类型,我们应该把他们当做结构体来看待,不能因为在linux系统上pthread_t被定义成int,就使用”==”来进行判断。
- start函数是有返回值的,该返回值可以从pthread_join()中取得,需要注意一点的是,因为start的返 回值可以由程序员自己指定的,很有可能把返回值指定成和PTHREAD_CANCELED相同的值,这样会 产生误解(因为pthread_cancel()会使线程的返回值为PTHREAD_CANCELED)。
- pthread_attr_t暂不讨论
- 在初始线程中,线程的启动函数(main函数)是从程序外部被调用的。比如在unix系统中将程序连接 到一个crt0.o文件上,该文件负责初始化进程,然后调用main函数。应该记住初始线程和普通线程存在着一些不同:main函数的调用参数(argc和argv)与普通线程的启动函数不同(void*);如果普通线程从启动函数中返回,则线程终止而其他线程依然可以运行,但如果初始进程从main函数中返回时,进程终止(进程内所有线程都被终止)。如果希望初始线程终止,而进程中的其他线程继续执行,则需要 在初始线程中调用pthread_exit而不是从main函数中return或exit(任意线程调用exit都会导致整个进程的退出)。--POSIX多线程程序设计中文版-p34
线程的终止
void
pthread_exit(void *retval)
注意点:
- retval指向了需要返回的指针,特别注意的是retval指向的地址千万别在线程栈上,因为随着线程的销毁,指针也会变得无效。
- 线程中的任何地方调用该函数都会让线程退出。
- 让线程退出的方法不只调用pthread_exit(),还可以在线程主程序中使用return。或使用pthread_cancel。特别注意的是任何地方调用exit()都会引起整个进程的退出。
线程的“加入”和“分离”
int
pthread_join(pthread_t thread, void **retval)
注意点:
- 如果在线程终止时,没有使用该函数来获得线程的返回值,那么线程将会出现僵尸状态(和僵尸进程一样)。
- pthread_join()中retval是指向pthread_exit()中retval的指针,请注意pthread_exit()中的第1个注意点。
- pthread_join和waitpid效果一样。区别在于,线程的地位是平等的,任何一个线程都可以调用pthread_join()。而waitpid()只有父进程才能调用。在进程中可以用waitpid(-1)来等待所有子进程,但在线程中没有这种功能(想在主线程中等待所有的线程终止,只能使用很复杂的condition variable)。
- 当pthread_join(pthread_self(), NULL)时,该函数会返回EDEADLK。
int
pthread_detach(pthread_t thread)
有些时候,我们并不太关心线程的退出状态。我们只是想让线程自己终止,然后清除掉他自己使用的资源。在这种情况下,我们就使用该函数来detach该线程。这样不会出现“僵尸”线程。分离一个正在运行的线程不会对线程代理任何影响,仅仅是通知系统当该线程结束时,其所有资源可以被回收。
线程id操作
pthread_t pthread_self(void);
int pthread_equal(pthread_t t1, pthread_t
t2);
阅读(2366) | 评论(1) | 转发(2) |