线程创建函数:pthread_create(thread,attr,start_routine,arg)
这个函数在pthread.h中,它的四个参数分别表示:
thread: 指向线程标识符的指针,传入时一般都用&thread[i]这样的写法(一般是多个线程,所以用线程数组)
attr: 线程参数,一般可以填成NULL
start_routine: 要运行函数的首地址,按照C的特性,传入函数指针即可
arg: 要运行函数的参数,如果没有参数,可以填成NULL 如果要使用,必须使用指针,并且必须是void指针。比如传入时写(void*)&(num[i])
该线程有返回值,返回值为0表示创建线程成功,反之失败。
-------------------------------------------------------------------------------
linnux中,线程退出有三种方式:执行完内容后自己退出;被同进程中的其他线程强行终止,或者通过pthread_exit()函数主动退出
线程中止函数:pthread_exit(void* retval)
可以使线程主动退出,它的参数是一个void指针,可以指向任何数据,但是不能将其指向局部变量,因为函数结束以后就没了嘛。类似于普通函数的返回值,如果没有要传递的值则为NULL。
注意:在使用此函数退出线程时,由于线程间共享资源,退出的线程资源不会被释放,如果需要可以用pthread_join来处理。
此时存在了一个问题:主线程中的结束一般用的都是return 0,但用多线程时应该使用pthread_exit()函数,因为return结束的话,如果主线程运行太快先结束,那其他子线程也要被迫结束掉
。所以需要换成pthread_exit(),这样就不会影响到其他线程运行(主线程资源已经释放,但没有退出)。子线程的退出也可以用pthread_exit()函数。
#include <iostream> // 必须的头文件 #include <pthread.h> using namespace std; #define NUM_THREADS 5 // 线程的运行函数 void* say_hello(void* args) { cout << "This is a test" << endl; return 0; } int main() { // 用pthread_t定义线程的 id 变量,多个变量使用数组 pthread_t tids[NUM_THREADS]; for(int i = 0; i < NUM_THREADS; ++i) { //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数 int ret = pthread_create(&tids[i], NULL, say_hello, NULL); if (ret != 0) { cout << "pthread_create error: error_code=" << ret << endl; } } //如果这里用return,主线程结束时子线程没运行完就会被强制结束; pthread_exit(NULL); }
因为exit()会调用线程清理功能,所以子线程最好使用pthread_exit()来结束,主线程根据需要,看情况用pthread_exit()或者return。
----------------------
线程连接和分离:
pthread_join(threadid,*retval)
pthread_detach(threadid)
在某些时候,主线程创建子线程时,子线程承担了大量计算任务,运行比主线程慢,但是主线程又需要用到子线程的计算结果,就需要主线程等待子线程。
线程在创建时会有一个属性,定义其是可连接(join)的还是分离(detach)的,可连接的话,该线程可以使用join函数连接,否则永远不能被连接。连接意味着一旦在主线程中调用该函数,则主线程会一直阻塞着,直到子线程运行完成。
jon()函数 : 包含两个参数,threadid是要连接的线程号,retval是指向子线程返回值的指针
在创建子线程后使用。主线程中使用join后,主线程就会阻塞,直到子线程结束。当join()函数返回后,被调用的线程才会真正结束。
返回值为0表示连接成功 其他均为失败
(注意:join只会清理系统清理的内存,malloc申请的空间仍需要手动释放,并且一个线程只能被一个线程连接)
初始将线程属性设置为可连接的方式:
#include <pthread.h> pthread_t threads[NUM_THREADS]; pthread_attr_t attr; // 初始化并设置线程为可连接的(joinable) pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
----------------------
注意:linux原生不带pthread库,如果要用,编译时指令要在 后面加上-pthread
例:g++ test.cpp -pthread -o test.o