线程的创建
线程库的头文件包含在头文件pthread.h中:
线程创建函数:int pthread_create(pthread_t *id,pthread_attr_t* attr,void*(*pthread_fun)(void*),void* arg);
pthread_fun函数是一个线程函数,即新创建的线程的执行体。pthread_create函数会创建出一条新的函数线程,线程从pthread_fun函数入口地址开始执行,到pthread_fun函数结束。参数中的id是线程创建时分配的线程id,应该传一个变量的地址将id值带出。arg参数为给pthread_fun函数传递的参数。attr为线程属性,默认为NULL。pthread_create函数成功返回0,失败返回错误码。该函数一般不会阻塞。
线程结束函数:void pthread_exit(void*);
主线程结束默认调用exit函数,这个函数会结束进程。进程结束,所有的线程也会随之结束。
等待线程结束函数:int pthread_join(pthread_t id,void**);
该函数会阻塞,直到等待的线程结束。
终止一个线程:int pthread_cancel(pthread_t id);
该函数只是发起取消请求,并不会阻塞。
创建线程时给函数线程传参的两种方式
1.值传递
最多传递4字节的数据,将传递的值直接强转为void*,记录的是传递的值。
void* fun(void* arg)
{
int data = (int)arg;
}
int main()
{
int data = 10;
pthread_t id;
int res = pthread_create(&id,NULL,fun,(void*)arg);
assert(0 == res);
return 0;
}
2.地址传递
将要传递的值的地址转化为void*,记录的是传递的值的地址。
void* fun(void* arg)
{
int data = *(int *)arg;
}
int main()
{
int data = 10;
pthread_t id;
int res = pthread_create(&id,NULL,fun,(void *)&data);
assert(0 == res);
return 0;
}
地址传递时函数线程中通过形参传递的地址对变量进行修改,会影响主线程中变量的值。同时主线程中对变量的修改,也会影响函数线程中变量的值。这也验证了同一进程中所有线程共享4G虚拟地址空间。
多线程的数据共享
由于线程是进程中的一条执行序列,所以一个进程中的所有线程共享全局、堆区数据,包括打开的文件描述符。只有栈区的数据是每个线程独享的。