1.守护进程
1.守护进程的特点
是后台服务进程
独立于控制终端
周期性执行某任务
不受用户登录注销影响
一般采用以d结尾的名字(服务)
2.进程组
进程的组长:
组里边的第一进程
进程组的ID==进程中的组长的ID
进程中组长的选择:
进程中的第一个进程
进程组ID的设定:
进程组的ID就是组长的进程ID
3.会话
创建一个会话注意事项:
不能是进程组长
创建会话的进程成为新进程组的组长
有些linux版本需要root权限执行此操作
创建出的新会话会丢弃原有的控制终端
一般步骤:fork ,父进程死掉,子进程执行创建会话操作(setsid)
获取进程所属的会话ID:
pid_t getsid(pid_t pid);
创建一个会话:
pid_t setsid(void);
4.创建守护进程模型
fork子进程,父进程退出
子进程创建新会话
改变当前工作目录chdir(不必须)
重设文件掩码(不必须)
关闭文件描述符
执行核心工作
2.线程的概念
主线程和子线程
共享:.text .bss .data 堆 动态加载区 环境变量 命令行参数
通信:全局变量,堆
不共享:栈——若共五个线程,栈区会被平均分成五块
在Linux下,线程就是进程——轻量级进程
对于内核来说,线程就是进程
多进程和多线程的区别:
多进程:始终共享的资源:代码、文件描述符、内存映射区---mmap
多线程:始终共享的资源:堆、全局变量——节省资源
安卓线程man page ,命令:
sudo apt-get install manpages-posix-dev
查看指定线程的LWP号——线程ID:
线程号和线程ID是有区别的
线程号是给内核看的
线程ID是我们程序员看的
查看方式(找到程序的进程ID): ps -Lf pid
例如:打开火狐浏览器
查看线程为3798的进程(ps -Lf 3798),发现所有的PID相同,LWP不相同
3.线程的创建
1.pthread_create创建线程
函数原型:
int pthread_create( pthread_t *thread, //线程ID = 无符号长整型
const pthread_attr_t *attr, //线程属性,NULL
void *(*start_routine)(void *), //线程处理函数
void *arg); //线程处理函数的参数
参数:
pthread:传出参数,线程创建成功之后,会被设置一个合适的值
attr:默认传NULL
start_routine:子线程的处理函数
arg: 回调函数的参数
返回值:成功:0 错误:错误号 //perror不能使用该函数打印错误信息
主线程先退出,子线程会被强制结束
验证线程直接共享全局变量
在main函数中创建一个线程,为主线程
创建主线程时,调用的函数为子线程的处理函数
若没有睡眠2s,主线程先退出,子线程会被强制结束
线程打印错误号和错误信息:
strerror();//获取错误信息
2.pthread_exit单个线程退出
函数原型: void pthread_exit(void *retval);
retval指针:必须指向全局变量,堆
在主线程创建之后,for循环执行之前,调用pthread_exit函数,会退出单个主线程
不会打印主线程的for函数,而子线程不会被影响
主线程在for函数之后调用pthread_exit函数
子线程在循环i=2时调用pthread_exit函数
主线程while循环,子线程在循环i = 2时,调用exit函数
主线程循环打印一会,就会退出进程
主线程while循环,子线程在循环i = 2时,调用pthread_exit函数,退出单个子线程
主线程一直循环打印
3.pthread_join阻塞等待线程退出,获取线程退出状态
函数原型:
int pthread_join(pthread_t pthread, void **retval)
参数:
pthread:要回收的子线程的ID
retval:读取线程退出的携带信息
传出参数
void* ptr;
pthread_join(pthid,&ptr);
指向的内存和pthread_exit参数指向地址一致
在主线程调用pthread_join函数
阻塞主线程并等待子线程退出后,执行剩余代码
4.pthread_detach线程分离
函数原型:int pthread_datach(pthread_t thread);
调用该函数之后不需要 pthread_join
子线程会自动回收自己的PCB
5.pthread_cancel杀死(取消)线程
函数原型: int pthread_cancel(pthread_t pthread);
使用注意事项:
在要杀死的子线程对应的处理的函数的内部,必须做过一次系统调用
write read printf
int a = 2; int b = a+3;
pthread_testcancel();设置取消点
6.pthread_equal比较两个线程ID是否相等(预留函数)
函数原型:
int pthread_equal(pthread_t t1,pthread_t t2);