windows下的多线程已经很熟悉了,本以为迁移到linux很容易,但总是感觉心里没底,函数名都不一样。所以现在把linux下的多线程完整的走一遍。
1、创建线程
windows下用_beginthreadex来开启一个线程,那么linux呢? 那就用pthread_create。相比之下,pthread_create参数更少,参数是pid, attr, startaddr, param。
头文件
#include<pthread.h>
函数声明
int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*start_rtn)(void*),void *arg);
编译链接参数
-pthread
返回值
若线程创建成功,则返回0。若线程创建失败,则返回出错编号,并且*thread中的内容是未定义的。返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数
用于指定各种不同的线程属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这
些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。
按照UNIX惯例,函数成功时返回0,失败时返回-1,但pthread_XXX系列函数并未遵循这个惯例,在pthread_XXX失败时返回的是错误码。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *thread_fun(void *param)
{
for ( int i = 0; i < 10; ++i)
{
printf("this is thread fun %d...\n", i);
}
}
int main()
{
pthread_t tid;
if ( 0 != pthread_create(&tid, NULL, thread_fun, NULL) )
{
printf("create thread failed!\n");
}
for ( int i = 0; i < 10; ++i)
{
printf("this is main function %d ...\n", i);
}
}
怎么全都是main function,难道线程创建失败了?做了判断了啊。其实这就是线程的第一个问题,和线程的调度有关,就详细说了,简单一句话:thread线程还没开始执行main就已经执行完了,由于main退出则进程结束,进程中的所有线程也就结束了,如果还要看,则可以把main中的 循环次数加大,则会看到thread也打印了。
2、等待线程
由前面可以知道,thread还没来得急执行main就退出了,那有没有什么办法呢?当然有,而且很多,只要能让main阻塞的操作都可以,比如:等待输入,sleep,空转循环等等。但这些始终感觉是小门小道,难登大雅之堂。在windows中有WaitForSingleObject来等待对象,linux中有pthread_join来等待。
函数pthread_join用来等待一个线程的结束。
头文件 :
#include <pthread.h>
函数定义:
int pthread_join(pthread_t thread, void **retval);
描述 :
pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
参数 :
thread: 线程标识符,即线程ID,标识唯一线程。retval: 用户定义的指针,用来存储被等待线程的返回值。
返回值 :
0代表成功。 失败,返回的则是错误号。
代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。所有线程都有一个线程号,也就是Thread ID。其类型为pthread_t。通过调用pthread_self()函数可以获得自身的线程号另外需要说明的是一个线程不能被多个线程等待,也就是说对一个线程只能调用一次pthread_join,否则只有一个能正确返回,其他的将返回ESRCH 错误。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
void *thread_fun(void *param)
{
for ( int i = 0; i < 10; ++i)
{
printf("this is thread fun %d...\n", i);
}
const static char *p = "I'am finish, thank you call me...";
return (void *)p;
}
int main()
{
pthread_t tid;
if ( 0 != pthread_create(&tid, NULL, thread_fun, NULL) )
{
printf("create thread f