6点注意事项
setsid
作用: 查看当前进程在的会话的id
pid_t getsid(pid_t pid);
参数:
pid: 要查看的进程的pid
0 : 本组的会话id
返回值:
成功: 当前的会话id
失败: -1, 设置errno
作用: 当当前进程不是组的组长时, 则创建一个新的会话, 然后使其成为会话组长和组组长
pid_t setsid(void);
返回值:
成功: 返回调用的进程的会话ID
失败: -1, 设置errno
是linux中后台服务进程, 通常独立于控制终端, 并且周期性的执行某种任务或等待处理某些发生的事情, 一般采用以d结尾的名字
守护进程的特点:
创建子进程, 父进程退出
在子进程中创建新会话
setsid()
改变当前目录位置
chdir()
重设文件权限掩码
umask()
防止继承的文件创建屏蔽字拒绝某些权限
关闭/重定向文件描述符
因为继承打开的文件不会用到, 浪费系统资源, 无法卸载
重定向: 将之前的文件重定向到/dev/null
开始执行守护进程核心工作, 守护进程退出处理程序模型
while()
作用: 改变当前工作目录的位置, 防止占用可卸载文件系统
int chdir(const char *path);
参数:
path: 目标目录的路径
返回值:
成功: 0
失败: -1, 设置errno
作用:
mode_t umask(mode_t mask);
参数:
mask: 8进制的值
返回值:
成功: 之前设置的值
线程是轻量级进程
进程和线程的区别:
pcb
pcb
在linux中, 线程是最小的执行单元, 进程是最小的资源分配单元
查看pid
程序的线程
ps -Lf <pid>
clone
文件描述符
每种信号的处理方式
信号处理方式: 哪个线程抢到了,哪个线程就处理他
当前工作目录
用户id和组id
内存地址空间
(.text/ .data/ .bss/ 共享库)
线程id
处理器现场和栈指针(内核栈)
独立的栈空间(用户栈空间)
errno变量(全局变量)
信号屏蔽字
可以指定某一个线程来处理一个特定的信号
调度优先级
优点:
缺点:
不能使用perror()
!!
fprintf(stderr, "xxx error: %s\n", strerror(ret));
作用:获取线程id
pthread_t pthread_self(void);
返回值:
当前线程的id
作用:创建一个新进程
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void *),
void *restrict arg);
参数:
thread: 传出参数, 新创建线程的线程id
attr: 线程属性, 默认为NULL
start_routine: 子线程回调函数, 创建成功, pthread_create函数返回时,该函数会被自动调用
arg: start_routine的参数, 若没有,则为NULL
返回值:
成功: 0
失败: 错误号, 且thread为定义
作用: 退出当前的线程(包括主线程)
noreturn void pthread_exit(void *retval);
参数:
retval: 推出值, 无推出值时, NULL
返回值:
无
比较:
exit()
退出当前进程return
返回到调用者pthread_exit()
推出当前线程作用:阻塞地回收指定的线程, 并且可以获取等待线程的返回值
int pthread_join(pthread_t thread, void **retval);
参数:
thread:传入参数, 待回收的线程id
reval: 传出参数, 为待回收的线程的退出值
若线程异常结束, 值为-1
返回值:
成功: 0
失败: 错误号
作用:杀死线程, 需要一个取消点(保存点)
int pthread_cancel(pthread_t thread);
参数:
thread: 待杀死的线程id
返回值:
成功: 0
失败: 错误号
注意:
pthread_cancel
无效,此时可以手动添加取消点 pthread_testcancel()
pthread_cancel()
杀死的线程, 返回-1, 使用pthread_join
来回收该值作用: 将指定的线程分离
int pthread_detach(pthread_t thread);
参数:
thread: 待分离的线程id
返回值:
成功: 0
失败: 错误号
分离了以后,当线程终止的时候,线程会自己回收自己的pcb
, 无需主线程用join
来回收
线程控制原语 | 进程控制原语 |
---|---|
pthread_create | fork |
pthread_self | getpid |
pthread_exit | exit |
pthread_join | wait/waitpid |
pthread_cancel | kill |
pthread_detach |
typedef struct
{
int __detachstate; // 线程的分离状态
int __schedpolicy; // 线程的调度策略
struct sched_param __schedparam; // 线程的调度参数
int __inheritsched; // 线程的继承性
int __scope; // 线程的作用域
size_t __guardsize; // 线程的缓冲区大小
int __stackaddr_set; // 线程的栈设置
void* __stackaddr; // 线程的栈位置
size_t __stacksize; // 线程的栈大小
} pthread_attr_t;
注意: 应该先初始化线程属性, 再pthread_create
创建线程
作用:初始化线程属性
int pthread_attr_init(pthread_attr_t *attr);
参数:
attr: 传出参数, 初始化以后的属性
返回值:
成功: 0
失败: 错误号
作用: 销毁线程属性所占用的资源
int pthread_attr_destroy(pthread_attr_t *attr);
参数:
attr: 待销毁的线程属性
返回值:
成功: 0
失败: 错误号
作用:设置当前线程分离的属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
参数:
attr: 传出参数, 待修改的属性值
detachstate: 线程分离的属性值
PTHREAD_CREATE_DETACHED(分离的)
PTHREAD_CREATE_JOINABLE(未分离的,默认的)
返回值:
成功: 0
失败: 错误号
作用: 获取当前线程分离的属性
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
参数:
attr: 已初始化的线程属性
detachstate: 传出参数, 当前线程的状态
返回值:
成功: 0
失败: 错误号
通过线程属性将一个线程设置为分离态
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr, tfn, NULL);
pthread_attr_destroy(&attr);
pthread_exit
pthread_join
pthread_detach
pthread_create
, 指定分离属性malloc
和mmap
申请的内存可被其他的线程释放fork
, 除非马上exec
.子进程中只有fork
线程存在, 其他的进程均要pthread_exit
(即,只存活了调用fork
的进程)