线程:
线程是执行粒度比进程小的执行流;线程是在进程的地址空间内运行的一个控制序列。
在Linux中线程有独立的PCB,为了实现在内核中进行切换有独立的上下文,调用函数时开辟栈帧有私有栈,线程有自己的调度优先级,自己的信号屏蔽字;各个线程共享一个进程地址空间,共享文件描述符表,遇到的异常信号处理方式相同,共享进程中的某些资源,各自完成进程分配的任务。
线程是如何进行标识的
每个线程都有属于自己的id,获取线程id有两种方式:
1. pthread_t pthread_self()
2. #include<sys/syscall.h>
pid_t tid;
tid=syscall(SYS_gettid);
线程是如何进行创建的
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void* (start_routine)(void*),void* arg)
参数:thread:标识线程的id;
attr:设置线程的属性,NULL表示默认属性;
start_routine:函数地址,线程启动时调用的函数;
arg:传给线程启动函数的参数。
返回值:成功返回0,失败返回错误码。
注:链接函数库时在Makefile里一定要使用编译器命令选项-lpthread
.
#include<stdio.h>
#include<stdlib.h>
void* thread_run(void* arg)
{
while(1)
{
printf("get a thread:%s\n",(char*)arg);
sleep(1);
}
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,thread_run,"thread-1");
while(1)
{
printf("I am main thread!\n");
sleep(2);
}
return 0;
}
线程如何终止
线程终止有三种方式:
1.void pthread_exit(void* value_ptr)
注:主线程的退出表示进程的退出,不能调用此函数,父进程获得进程的退出码,所以需要以进程的方式进行退出。
2.int pthread_cancel(pthread_t thread)
注意:线程不能在自己的执行函数中取消自己。
成功返回0,失败返回错误码。
3.线程函数中return返回
线程的等待和分离
//线程等待
int pthread_join(pthread_thread,void** value_ptr)
参数:thread:线程id;
value_ptr:指向一个指针,这个指针指向线程的返回值。
返回值:成功返回0,失败返回错误码
线程退出时,空间没有被释放,需要执行此函数对空间进行清理;
保证新建的线程不会复用刚才线程退出的地址空间。
//线程分离
1.线程组内其他进程对目标进程进行分离
int pthread_detach(pthread_t thread)
2.线程自己分离
int pthread_detach(pthread_t pthread_self())
#include<stdio.h>
#include<stdlib.h>
void* thread_run(void* arg)
{
printf("I am %s\n",(char*)arg);
sleep(1);
return (void*)1;
}
int main()
{
pthread_t tid;
void* tmp;
pthread_create(&tid,NULL,thread_run,"thread");
pthread_detach(tid);//线程分离
pthread_join(tid,&tmp);//线程等待
printf("main thread is run,thread return!tmp:%d\n",(int)tmp);
return 0;
}
线程分离之后,当线程退出的时候不需要再进行线程等待进行空间的释放清理,这些工作自动化完成。