守护进程:
daemo进程,通常运行于操作系统后台,脱离控制终端,一般不与用户交互,周期性的执行某种任务或等待处理某些等待处理发生的时间。
创建守护进程模型:
1、创建子进程 父进程退出:
fork子进程 终止父进程->目的为了创建会话setsid函数
2、在子进程中创建新会话
setsid()函数----->创建会话,使子进程完全独立出来,脱离控制。
3、改变当前目录位置 chdir()
4、重设文件权限掩码
防止继承的文件创建屏蔽字拒绝某些权限,增加守护进程的灵活性
5、关闭文件、重定向描述符
6、守护进程 业务逻辑 一般while
=====================================================
线程-------------最小的执行单位
什么是线程:LWP轻量级的进程------>本质还是进程
进程和线程的区别:
进程:有独立的进程地址空间 有独立的PCB
线程:有独立的PCB,没有独立的进程地址空间 是否共享进程地址空间?
ps -Lf 进程ID------->线程号
线程共享资源:
1、文件描述符表
2、每种信号的处理方式(mask不共享)
3、当前的工作目录
4、用户ID和组ID
5、内存地址空间
线程非共享资源:
1、线程id
2、处理器现场(寄存器的值)和栈指针(内核栈)-------------->只要是栈 都是不共享的
3、独立的栈空间(用户空间栈)
4、errno变量----->全局变量
5、信号屏蔽字
6、调度优先级
线程控制源语:
pthread_t pthrea_self 获取线程ID 对应进程------》getpid() 线程id 是在进程地址空间内部
用来表示线程身份的id号
int pthread_create(pthread_t *tid,const pthread_attr_t *,void*(*start_routn)(void *) 创建一个新线程
参数1:传出参数,代表新的tid;
参数2:线程属性
参数3:子线程回调函数 创建成功,pthread_create创建成功 该函数会被调用
参数4:参3的参数
练习循环创建5个线程:要求用到回调函数里面的参数打印\
练习 线程共享全局变量测试
void pthread_exit()退出单个线程
retval:退出值 无退出值 NULL
exit()
return:
pthread_exit();退出当前线程
int pthread_join(pthread_t,void **retval);
// date: 2023年07月21日 星期五 20时59分40秒
/// player: wenrou
/// // path: /mnt/hgfs/LuinxFile/GEC_2301/05_系统编程/08_线程/pthread_join.c /
// date: 2023年07月05日 星期三 00时38分41秒
/// player: wenrou
/// // path: /etc/templates/skeleton.c
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
void *tfc(void *arg)
{
return (void*)74;
}
int main(int argc, char *argv[])
{
//创建一个进程
pthread_t tid;
int *retval;
int ret = pthread_create(&tid,NULL,tfc,NULL);
if(ret != 0)
{
perror("pthread_create");
}
ret = pthread_join(tid,(void **)&retval);
if(ret != 0)
{
perror("pthread_join");
}
printf("child thread exit with %d\n",(void *)retval);
pthread_exit(NULL);
return 0;
}
int pthread_cancle(pthread_t tid) 杀死线程
终止线程的方法:
1、return
2、pthread_exit()
3、pthread_cancel()
// date: 2023年07月22日 星期六 21时41分11秒
/// player: wenrou
/// // path: /mnt/hgfs/LuinxFile/GEC_2301/05_系统编程/08_线程/pthread_endof3.c /
// date: 2023年07月05日 星期三 00时38分41秒
/// player: wenrou
/// // path: /etc/templates/skeleton.c
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
void *tfn1(void *arg)
{
printf("thread 1 returning\n");
return ((void*)1111);
}
void *tfn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void*)222);
}
void *tfn3(void *arg)
{
while(1)
{
printf("thread 3 returning\n");
sleep(1);
}
pthread_testcancel();
return (void*)666;
}
int main(int argc, char *argv[])
{
int ret;
pthread_t tid;
void *tret = NULL;
pthread_create(&tid,NULL,tfn1,NULL);
if(ret!=0)
{
perror("pthread_creat");
}
pthread_join(tid,&tret);
printf("thread 1 exit code = %d\n\n",(int)tret);
pthread_create(&tid,NULL,tfn2,NULL);
if(ret!=0)
{
perror("pthread_creat");
}
pthread_join(tid,&tret);
printf("thread 2 exit code = %d\n\n",(int)tret);
pthread_create(&tid,NULL,tfn3,NULL);
if(ret!=0)
{
perror("pthread_creat");
}
pthread_cancel(tid);
pthread_join(tid,&tret);
printf("thread 3 exit code = %d\n\n",(int)tret);
sleep(3);
return 0;
}
线程分离 int pthread_detach(pthread_t tid)
#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>
void *tfnc(void *arg)
{
// int i = (int)arg;
printf("thread:i am th pid =%d,tid = %lu\n",getpid(),pthread_self());
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid;
int ret = pthread_create(&tid,NULL,tfnc,NULL);
if(ret != 0)
{
perror("create");
}
sleep(1);
ret = pthread_detach(tid);
if (ret != 0)
{
perror("detach error");
}
ret = pthread_join(tid,NULL);
if (ret!=0)
{
perror("pthread_join error");
}
printf("main: pid =%d,tid = %lu\n",getpid(),pthread_self());
pthread_exit((void*)0);
return 0;
}
线程和进程源语比对:
函数 | 进程 | |
pthread_self() | getpid() | |
pthread_create() | fork() | |
pthread_cancel() | kill | |
pthread_exit() | exit() | |
pthread_join() | wait() | |
pthread_detach() |
线程属性初始化(了解)
int pthread_attr_init()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
void *tfn(void *arg)
{
printf("thread: pid = %d, tid = %lu\n", getpid(), pthread_self());
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid;
pthread_attr_t attr;
int ret = pthread_attr_init(&attr);
if (ret != 0) {
fprintf(stderr, "attr_init error:%s\n", strerror(ret));
exit(1);
}
ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置线程属性为 分离属性
if (ret != 0) {
fprintf(stderr, "attr_setdetachstate error:%s\n", strerror(ret));
exit(1);
}
ret = pthread_create(&tid, &attr, tfn, NULL);
if (ret != 0) {
perror("pthread_create error");
}
ret = pthread_attr_destroy(&attr);
if (ret != 0) {
fprintf(stderr, "attr_destroy error:%s\n", strerror(ret));
exit(1);
}
ret = pthread_join(tid, NULL);
if (ret != 0) {
fprintf(stderr, "pthread_join error:%s\n", strerror(ret));
exit(1);
}
printf("main: pid = %d, tid = %lu\n", getpid(), pthread_self());
pthread_exit((void *)0);
}