5守护进程与线程
进程组
多个进程的集合,第一个进程就是组长,组长进程的PID等于进程组ID。
进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组)。与组长进程是否终止无关。
一个进程可以为自己或子进程设置进程组 ID
相关函数
pid_t getpgrp(void);
得到当前进程所在的进程组的组 IDpid_t getpgid(pid_t pid);
获取指定的进程所在的进程组的组 ID,参数 pid 就是指定的进程,0当前进程int setpgid(pid_t pid, pid_t pgid);
将某个进程移动到其他进程组中或者创建新的进程组参数:pid: 某个进程的进程 IDpgid: 某个进程组的组 ID如果 pgid 对应的进程组存在,pid 对应的进程会移动到这个组中,pid != pgid如果 pgid 对应的进程组不存在,会创建一个新的进程组,因此要求 pid == pgid, 当前进程就是组长了返回值:函数调用成功返回 0,失败返回 - 1
setpgid设置子进程组id
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main(int argc, char *argv[])
{pid_t pid;pid = fork();if(pid == 0 ){printf("我是子进程:%d,我的进程组id是:%d\n",getpid(),getpgrp());setpgid(pid,pid); //设置子进程的组id为自己的pid,默认是父进程的pidprintf("我是子进程:%d,我的进程组id是:%d\n",getpid(),getpgrp());}else if(pid > 0){sleep(1);printf("我是父进程:%d,我的进程组id是:%d\n",getpid(),getpgrp());wait(NULL);}return 0;
}
会话
多个进程组的集合
获取进程所属的会话 ID
pid_t getsid(pid_t pid);
成功:返回调用进程的会话 ID;失败:-1,设置 errno
pid 为 0 表示察看当前进程 session ID创建一个会话,并以自己的 ID 设置进程组 ID,同时也是新会话的 ID。
pid_t setsid(void);
成功:返回调用进程的会话 ID;失败:-1,设置 errno
调用了 setsid 函数的进程,既是新的会长,也是新的组长。
注意事项:
调用进程不能是进程组组长,该进程变成新会话首进程(session header),建立新会话时,先调用 fork, 父进程终止,子进程调用 setsid(),
#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[])
{pid_t pid;pid = fork();if(pid == 0){printf("我是子进程id:%d,进程组id:%d,会话id:%d\n",getpid(),getpgid(0),getsid(0));printf("change--------------\n");sleep(2);setsid();printf("我是子进程id:%d,进程组id:%d,会话id:%d\n",getpid(),getpgid(0),getsid(0));}else{sleep(3);printf("我是父进程id:%d,进程组id:%d,会话id:%d\n",getpid(),getpgid(0),getsid(0));}return 0;
}
编译执行结果
我是子进程id:44801,进程组id:44800,会话id:39560 #默认子进程的进程组id是父进程的pid,会话id是当前bash的pid
change--------------
我是子进程id:44801,进程组id:44801,会话id:44801 #setsid后,进程组id,会话id都变成子进程的pid
我是父进程id:44800,进程组id:44800,会话id:39560
守护进程
daemon进程。通常运行与操作系统后台,脱离控制终端。一般不与用户直接交互。周期性的等待某个事件发生或周期性执行某一动作。
不受用户登录注销影响。通常采用以d结尾的命名方式。
Linux 后台的一些系统服务进程,没有控制终端,不能直接和用户交互。不受用户登录、注销的影响,一直在运行着,他们都是守护进程。
创建守护进程
创建守护进程,最关键的一步是调用 setsid 函数创建一个新的 Session,并成为 Session Leader。
1. fork子进程,让父进程终止。2. 子进程调用 setsid() 创建新会话3. 通常根据需要,改变工作目录位置 chdir(), 防止目录被卸载。4. 通常根据需要,重设umask文件权限掩码,影响新文件的创建权限。 022 -- 755 0345 --- 432 r---wx-w- 4225. 通常根据需要,关闭/重定向 文件描述符6. 守护进程 业务逻辑。while()
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <string.h>void func(int signo)
{int fd1;fd1 = open("./lc.txt",O_RDWR|O_CREAT|O_APPEND,0664); //fd1 = 3 符合默认的习惯if(fd1 == -1 ){perror("open lc.txt error");exit(1);}char *str="heppy new year\n";write(fd1,str,strlen(str));close(fd1);
}int main(int argc, char *argv[])
{pid_t pid;int fd,fd1;pid = fork();if(pid > 0){exit(1);}pid_t pid1 = setsid();if(pid1 == -1 ){perror("open lc.txt error");exit(1);}chdir("/home/lc"); //切换到一个不可能被删除卸载的目录umask(0022); //默认umask是0002,默认创建普通文件默认属性是664close(STDIN_FILENO); //close 0fd = open("/dev/null",O_RDWR); //fd = 0if(fd == -1 ){perror("open /dev/null error");exit(1);}dup2(fd, STDOUT_FILENO); // 重定向 stdout和stderr 1 -->0dup2(fd, STDERR_FILENO); // 2--> 0,//捕捉信号struct sigaction act;act.sa_handler = func;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGALRM,&act,NULL);
// signal(SIGALRM,func);//设置定时器struct itimerval it;it.it_interval.tv_sec = 10;it.it_interval.tv_usec = 0;it.it_value.tv_sec = 10;it.it_value.tv_usec = 0;setitimer(ITIMER_REAL,&it,NULL);while (1); // 模拟 守护进程业务.return 0;
}
线程
LWP,(light weight process)轻量级的进程,在linux环境下线程的本质仍然是进程,
进程:有独立的 进程地址空间。有独立的pcb。 分配资源的最小单位。可看成是只有一个线程的进程线程:有独立的pcb。没有独立的进程地址空间。 最小单位的执行。
[root@lc133 ~]# ps -aux | grep mysql | grep -v grep
mysql 1620 0.4 20.2 1793004 405880 ? Ssl 08:20 1:36 /usr/sbin/mysqld
Ssl:休眠,拥有子进程,多线程
[root@lc133 ~]# ps -Lf 1620
UID PID PPID LWP C NLWP STIME TTY STAT TIME CMD
mysql 1620 1 1620 0 38 08:20 ? Ssl 0:01 /usr/sbin/mysqld
mysql 1620 1 1669 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1670 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1671 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1672 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1674 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1675 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1676 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1677 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1678 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1679 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1680 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1724 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1725 0 38 08:20 ? Ssl 0:04 /usr/sbin/mysqld
mysql 1620 1 1726 0 38 08:20 ? Ssl 0:04 /usr/sbin/mysqld
mysql 1620 1 1727 0 38 08:20 ? Ssl 0:04 /usr/sbin/mysqld
mysql 1620 1 1728 0 38 08:20 ? Ssl 0:04 /usr/sbin/mysqld
mysql 1620 1 1729 0 38 08:20 ? Ssl 0:55 /usr/sbin/mysqld
mysql 1620 1 1786 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1787 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1788 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1793 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1794 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1797 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1799 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1802 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1803 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1804 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1811 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1812 0 38 08:20 ? Ssl 0:05 /usr/sbin/mysqld
mysql 1620 1 1814 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1815 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1816 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1817 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1830 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1831 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1832 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqld
mysql 1620 1 1836 0 38 08:20 ? Ssl 0:00 /usr/sbin/mysqldlwp:线程号
系统会给mysql进程1620分配进程地址空间,内核空间拥有pid1620的pcb。
pid1620进程创建线程时,本身也成了主线程。创建的线程分别拥有自己独立的pcb,处在同一内核空间中。
线程更加节省系统资源,效率不仅可以保持的,而且能够更高在一个地址空间中多个线程独享:每个线程都有属于自己的栈区,寄存器 (内核中管理的)1.线程 id2.处理器现场和栈指针(内核栈)3.独立的栈空间(用户空间栈)4.errno 变量5.信号屏蔽字6.调度优先级在一个地址空间中多个线程共享:代码段,堆区,全局数据区,打开的文件 (文件描述符表) 都是线程共享的1.文件描述符表2.每种信号的处理方式3.当前工作目录4.用户 ID 和组 ID5.内存地址空间 (.text/.data/.bss/heap/共享库)每个进程对应一个虚拟地址空间,一个进程只能抢一个 CPU 时间片一个地址空间中可以划分出多个线程,在有效的资源基础上,能够抢更多的 CPU 时间片一个进程创造线程并不是越多越好优点: 1. 提高程序并发性 2. 开销小 3. 数据通信、共享数据方便
缺点: 1. 库函数,不稳定 2. 调试、编写困难、gdb 不支持 3. 对信号支持不好
优点相对突出,缺点均不是硬伤。Linux 下由于实现方法导致进程、线程差别不是很大。
pthread_self获取当前线程id
获取线程 ID。其作用对应进程中 getpid() 函数。pthread_t pthread_self(void);返回值:成功:0; 失败:无!线程 ID:pthread_t 类型,本质:在 Linux 下为%lu无符号整数,其他系统中可能是结构体实现线程 ID 是进程内部,识别标志。(两个进程间,线程 ID 允许相同)注意:在子线程中通过使用pthread_self,获得线程id。
pthread_create创建线程
创建一个新线程。 其作用对应进程中 fork() 函数。int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);返回值:成功:0; 失败:错误号 -----Linux 环境下,所有线程特点,失败均直接返回错误号。参数:pthread_t:当前 Linux 中可理解为:typedef unsigned long int pthread_t;参数 1:传出参数,保存系统为我们分配好的线程 ID参数 2:通常传 NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。参数 3:函数指针,指向线程主函数(线程体),该函数运行结束,则线程结束。参数 4:线程主函数执行期间所使用的参数。传参。
pthread_exit退出当前线程
void pthread_exit(void *retval); 退出当前线程。参数:线程退出的时候携带的数据,当前子线程的主线程会得到该数据。如果不需要使用,指定为 NULL几个退出函数:exit(); 退出当前进程。后续代码不会执行return: 返回到调用者那里去。pthread_exit(): 退出当前线程。不影响其他进程
循环创建线程
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>void *func(void *arg)
{int i = (int)arg;printf("我是第%d子线程线程id:%lu,主线程是:%d\n",i+1,pthread_self(),getpid());//return NULL;if(i==4){while(1);}pthread_exit(NULL);
}int main(int argc, char *argv[])
{pthread_t tid;int i;for(i = 0; i < 5; i++){int ret = pthread_create(&tid,NULL,func,(void*)i);if(ret != 0){perror("pthread_create error");exit(1);}}//sleep(1);printf("我是主线程线程id:%lu,主线程是:%d\n",pthread_self(),getpid());//while(1);//return 0;pthread_exit(NULL);
}
主线程 pthread_exit(NULL);只退出当先线程,不会对其他线程造成影响。
[lc@lc133 pthread]$ gcc pthread.c -lpthread
pthread.c: 在函数‘func’中:
pthread.c:8:10: 警告:将一个指针转换为大小不同的整数 [-Wpointer-to-int-cast]int i = (int)arg;^
pthread.c: 在函数‘main’中:
pthread.c:23:43: 警告:将一个整数转换为大小不同的指针 [-Wint-to-pointer-cast]int ret = pthread_create(&tid,NULL,func,(void*)i);^
[lc@lc133 pthread]$ ./a.out
我是主线程线程id:140307387344704,主线程是:25356
我是第3子线程线程id:140307362223872,主线程是:25356
我是第2子线程线程id:140307370616576,主线程是:25356
我是第1子线程线程id:140307379009280,主线程是:25356
我是第4子线程线程id:140307353831168,主线程是:25356
我是第5子线程线程id:140307345438464,主线程是:25356
[root@lc133 ~]# ps -aux | grep a.out #使用pthread_exit主线程已退出,子线程还在,使用return函数,主线程退出,子进程也会退出
lc 25356 100 0.0 0 0 pts/1 Zl+ 14:51 0:58 [a.out] <defunct>
root 25373 0.0 0.1 112840 2512 pts/0 S+ 14:52 0:00 grep --color=auto a.out
pthread_join阻塞 回收线程
int pthread_join(pthread_t thread, void **retval); 阻塞 回收线程。thread: 待回收的线程idretval:传出参数。 回收的那个线程的退出值。线程异常借助,值为 -1。返回值:成功:0失败:errno
pthread_exit可以传出指针,数值,要注意数据格式的强转。
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>struct student
{int age;char name[256];
};void *func(void *arg)
{printf("child thread,process id is %d,thread id is %lu\n",getpid(),pthread_self());struct student *luci;luci = malloc(sizeof(struct student));memset(luci,0,sizeof(luci));luci->age = 17;strcpy(luci->name,"luci");pthread_exit((void *)luci);
}int main(int argc, char *argv)
{printf("main thread,process id is %d,thread id is %lu\n",getpid(),pthread_self());pthread_t tid;int ret = pthread_create(&tid,NULL,func,NULL);if(ret != 0){perror("pthread_creade error");exit(1);}struct student *retval;//pthread_join 传出参数retval是void**类型的ret = pthread_join(tid,(void **)&retval);if(ret != 0){perror("pthread_jion error");exit(1);}printf("child thread exit.\n");printf("age = %d ,name = %s \n",retval->age,retval->name);return 0;
}
#include <stdio.h>
#include <pthread.h>void *func(void *arg)
{printf("child pthread id : %lu\n",pthread_self());pthread_exit((void*)66);
}int main(){pthread_t tid;int *retval;pthread_create(&tid,NULL,func,NULL);pthread_join(tid,(void**)&retval) ;printf("main pthread receive : %d\n",(void *)retval);pthread_exit(NULL);
}
pthread_detach 设置线程分离
int pthread_detach(pthread_t thread); 设置线程分离thread: 待分离的线程id返回值:成功:0失败:errno
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>void *func(void *arg)
{int i;for( i = 0;i < 5; i++){sleep(1);printf("i = %d \n",i);}pthread_exit(NULL);}
int main()
{pthread_t tid;int ret;ret = pthread_create(&tid,NULL,func,NULL);if(ret != 0){fprintf(stderr,"pthread_create error:%d",strerror(ret));exit(1);}pthread_detach(tid);ret = pthread_join(tid,NULL);//线程分离后主线程就不能回收了,报错:无效的参数if(ret != 0){fprintf(stderr,"pthread_join error:%s",strerror(ret));exit(1);}pthread_exit(NULL);return 0;
}
pthread_cancel杀死一个线程
int pthread_cancel(pthread_t thread); 杀死一个线程。 需要到达取消点(保存点)thread: 待杀死的线程id返回值:成功:0失败:errno在线程 A 中调用线程取消函数 pthread_cancel,指定杀死线程 B,这时候线程 B 是死不了的,只有在线程 B 中进程进行一次系统调用(从用户区切换到内核区),这个节点会被pthread_cancel杀死,否则线程 B 可以一直运行。与信号不同,进程会优先处理信号。如果,子线程没有到达取消点, 那么 pthread_cancel 无效。我们可以在程序中,手动添加一个取消点。使用 pthread_testcancel();成功被 pthread_cancel() 杀死的线程,返回 -1.使用pthead_join 回收。
pthread_equal判断线程id是否相同
int pthread_equal(pthread_t t1, pthread_t t2);参数:t1 和 t2 是要比较的线程的线程 ID返回值:如果两个线程 ID 相等返回非 0 值,如果不相等返回 0
与进程函数相比
线程控制原语 进程控制原语pthread_create() fork();pthread_self() getpid();pthread_exit() exit(); / return pthread_join() wait()/waitpid()pthread_cancel() kill()pthread_detach()
创建线程时设置线程分离属性
pthread_create函数中参数 pthread_attr_t 是一个结构体
typedef struct
{int detachstate; // 线程的分离状态int schedpolicy; // 线程调度策略structsched_param schedparam; // 线程的调度参数int inheritsched; // 线程的继承性int scope; // 线程的作用域size_t guardsize; // 线程栈末尾的警戒缓冲区大小int stackaddr_set; // 线程的栈设置void* stackaddr; // 线程栈的位置size_t stacksize; // 线程栈的大小
} pthread_attr_t;
步骤:pthread_attr_t attr 创建一个线程属性结构体变量pthread_attr_init(&attr); 初始化线程属性,成功:0;失败:错误号pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);设置线程属性为 分离态//detachstate: PTHREAD_CREATE_DETACHED(分离线程)// PTHREAD _CREATE_JOINABLE(非分离线程)//获取程属性,分离 or 非分离//int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate); //参数: attr:已初始化的线程属性pthread_create(&tid, &attr, tfn, NULL); 借助修改后的 设置线程属性 创建为分离态的新线程pthread_attr_destroy(&attr); 销毁线程属性,成功:0;失败:错误号
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>void *func(void *arg)
{printf("hello wrold.\n");pthread_exit(NULL);
}int main()
{pthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);int val;pthread_attr_getdetachstate(&attr,&val);printf("属性:%d\n",val);pthread_t tid;pthread_create(&tid,&attr,func,NULL);pthread_attr_destroy(&attr);sleep(1);int ret = pthread_join(tid,NULL);if(ret != 0){fprintf(stderr,"pthread_join error : %s\n",strerror(ret));exit(1);}pthread_exit(NULL);return 0;
}
[lc@lc pthread]$ ./a.out
属性:1
hello wrold.
pthread_join error : Invalid argument
//pthread_join报错成功分离
注意事项
1. 主线程退出其他线程不退出,主线程应调用 pthread_exit
2. 避免僵尸线程
pthread_join
pthread_detach
pthread_create 指定分离属性
被 join 线程可能在 join 函数返回前就释放完自己的所有内存资源,所以不应当返回被回收线程栈中的值;
3. malloc 和 mmap 申请的内存可以被其他线程释放
4. 应避免在多线程模型中调用 fork 除非,马上 exec,子进程中只有调用 fork 的线程存在,其他线程在子进程
中均 pthread_exit
5. 信号的复杂语义很难和多线程共存,应避免在多线程引入信号机制
相关文章:
5守护进程与线程
进程组 多个进程的集合,第一个进程就是组长,组长进程的PID等于进程组ID。 进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组)。与组长进程是否终止无关。 一个进程可以为自己或子进程设置进程组 ID 相关函数 pid_t …...
EZ-Cube简易款下载器烧写使用方法
一、硬件连接 跟目标芯片接4根线 VCC、GND、TOOL、REST 四根线,如果板子芯片自己外接电源的,VCC 线可以不接。 二、 安装烧写软件和驱动 烧写软件:https://download.csdn.net/download/Stark_/87444744?spm1001.2014.3001.5503 驱动程序&a…...
sql server安装并SSMS连接
博主简介:原互联网大厂tencent员工,网安巨头Venustech员工,阿里云开发社区专家博主,微信公众号java基础笔记优质创作者,csdn优质创作博主,创业者,知识共享者,欢迎关注,点赞ÿ…...
Python_pytorch (二)
python_pytorch 小土堆pytotch学习视频链接 from的是一个个的包(package) import 的是一个个的py文件(file.py) 所使用的一般是文件中的类(.class) 第一步实例化所使用的类,然后调用类中的方法(def) Torchvision 数据集 数据集使用(CI…...
java手机短信验证,并存入redis中,验证码时效5分钟
目录 1、注册发送短信账号一个账号 2、打开虚拟机,将redis服务端打开 3、创建springboot工程,导入相关依赖 4、写yml配置 5、创建controller层,并创建controller类 6、创建service层,并创建service类 7、创建工具类&#x…...
kubectl命令控制远程k8s集群(Windows系统、Ubuntu系统、Centos系统)
文章目录1. 本地是linux2. 本地是Windows1. 本地是linux 安装kubectl命令 法一:从master的/usr/bin目录下拷贝kubectl文件到本机/usr/bin目录下法二:GitHub下载kubectl文件 在家目录下创建.kube目录config文件 法一:将master上对应用户的~/.…...
【求解器-COPT】COPT的版本更新中,老版本不能覆盖的问题
【求解器-COPT】COPT的版本更新中,老版本不能覆盖的问题方法1方法2如果license还是找不到作者:刘兴禄 参考网址: COPT的下载和配置步骤如下: 教程 | Windows系统下如何安装COPT求解器并配置许可文件: https://zhuan…...
Vue3.0文档整理:一、简介
1.1:什么是vue? Vue是一款用于构建用户界面的javascript框架;它基于标准HTML、CSS和Javascript构建,并提供了一套声明式、组件化的编程模型,帮助你高效的开发用户界面。 1.2:MVVM工作原理 MVVM指的是model、view和vie…...
vue2 diff算法及虚拟DOM
概括:diff算法,虚拟DOM中采用的算法,把树形结构按照层级分解,只比较同级元素,不同层级的节点只有创建和删除操作。 一、虚拟DOM (1) 什么是虚拟DOM? 虚拟 DOM (Virtual DOM,简称 VDOM) 是一种…...
Ray和极客们的创新之作,2月18日来发现
所在论坛:数据库技术创新&云原生论坛分享时段:2.18 10:30-11:00分享主题:云原生数据库PieCloudDB :Unbreakable安全特性剖析分享嘉宾:王淏舟,拓数派资深研发工程师 由中国开源软件推进联盟PostgreSQL分…...
Dubbo 源码分析 – 集群容错之 Router
1. 简介 上一篇文章分析了集群容错的第一部分 – 服务目录 Directory。服务目录在刷新 Invoker 列表的过程中,会通过 Router 进行服务路由。上一篇文章关于服务路由相关逻辑没有细致分析,一笔带过了,本篇文章将对此进行详细的分析。首先&…...
行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)
行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测) 目录 行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测) 1. 前言 2. 人体检测数据集说明 3. 基于YOLOv5的人体检测模型训练 4.人体检测模型…...
【图像分类】基于PyTorch搭建LSTM实现MNIST手写数字体识别(单向LSTM,附完整代码和数据集)
写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 提起LSTM大家第一反应是在NLP的数据集上比较常见,不过在图片分类中,它同样也可以使用。我们以比较熟悉的 mnist…...
Kotlin 1.8.0 现已发布,有那些新特性?
文章目录**如何安装 Kotlin 1.8.0****如果您遇到任何问题****更多文章和视频**结语Kotlin 1.8.0 版本现已发布,以下是其部分最大亮点: JVM 的新实验性功能:递归复制或删除目录内容提升了 kotlin-reflect 性能新的-Xdebug编译器选项ÿ…...
likeshop单商户SaaS商城系统—无限多开,搭建多个商城
likeshop单商户SaaS商城系统:适用于多开(SaaS)、B2C、单商户、自营商城场景,完美契合私域流量变现闭环交易使用,系统拥有丰富的营销玩法,强大的分销能力,支持DIY多模板,前后端分离。…...
Bean(Spring)的执行流程和生命周期
Bean(Spring)的执行流程具体的流程就和我们创建Spring基本相似。启动 Spring 容器 -> 实例化 Bean(分配内存空间,从无到有) -> Bean 注册到 Spring 中(存操作) -> 将 Bean 装配到需要的…...
工作记录------PostMan自测文件导入、导出功能
工作记录------PostMan自测文件导入、导出功能 测试文件导出 背景:写了一个文件下载功能,是数据写到excel中,下载,使用PostMan点击send后,返回报文是乱码。 解决办法: 点击send下面的 send and Downlo…...
上海亚商投顾:沪指震荡上行 大消费板块全线走强
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。市场情绪三大指数今日震荡反弹,沪指全天低开高走,深成指、创业板指均涨超1%。工程机械板块集体大涨&a…...
linux中的图形化UDP调试工具
sokit freeware version: 1.3.1 (GPLv3) website: https://github.com/sinpolib/sokit/ 这是一个TCP / UDP数据包收发和传输工具 linux汉化 默认是英文版本的,如果想使用中文,把软件目录下的sokit.lan_rename重命令为sokit.lan再次打开软件就发现已经…...
前端react面试题指南
概述下 React 中的事件处理逻辑 抹平浏览器差异,实现更好的跨平台。避免垃圾回收,React 引入事件池,在事件池中获取或释放事件对象,避免频繁地去创建和销毁。方便事件统一管理和事务机制。 为了解决跨浏览器兼容性问题࿰…...
深入浅出原核基因表达调控(乳糖操纵子、色氨酸操纵子)
原核基因表达调控 前言 自然界里,能量时有时无,各种生命为了让自己能够活下去,需要适应环境,在不同的环境合成不同的蛋白质。 原核生物体内有很多细胞,细胞里面有很多蛋白质,但是这些蛋白质在这些细胞里…...
10分钟理解Mysql索引
一、索引介绍 索引是什么 官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。 一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘…...
nVisual综合布线可视化管理系统解决方案
一、综合布线管理系统的必要性 如今企事业单位办公人员变化很快,如果还是采用传统方式通过工程竣工图或者网络拓扑图来进行网络维护工作会非常麻烦,并且对管理人员的要求也会很高,管理人员需要清楚的知道工作区的信息点与配线架点之间的对…...
34岁测试工程师被辞退,难道测试岗位真的只是青春饭吗?
一:前言:人生的十字路口静坐反思 入软件测试这一行至今已经10年多,承蒙领导们的照顾与重用,同事的支持与信任,我的职业发展算是相对较好,从入行到各类测试技术岗位,再到测试总监,再…...
Java中常见的空指针异常
参考链接: java中什么是空指针异常以及为什么会产生空指针异常天上的云川的博客-CSDN博客什么是java空指针 java中容易产生空指针异常:NullPointerException的场景火龙映天的博客-CSDN博客java怎么制造空指针异常 java空指针异常是什么、怎么发生、如何…...
d亚当替换工厂模式
对象工厂替代方案 一般,需要无需用模块构造器触发d运行时的挑剔循环检测的方法来注册工厂.很多时候,混合模块构造器正是想要方法,但它有全局全开或全闭的循环检测算法. 要全局关闭它,请在Main文件中,添加以下代码行: extern(C) __gshared string[] rt_options ["oncycl…...
Real-time Scene Text Detection with Differentiable Binarization
Abstract 近年来,基于分割的方法在文本检测场景中非常流行,因为分割结果可以更准确地描述曲线文本等各种形状的场景文本。然而,二值化的后处理对于分割检测是必不可少的,它将分割方法产生的概率图转换为文本框/区域。本文提出了一…...
国外客户只想跟工厂合作?可以这样破解
1.客户是愿意和外贸公司合作还是更愿意和工厂合作?一个外贸公司的朋友说:“我去工厂接待过七八次外国人,基本上都是英国、德国、日本、加拿大、美国的。”贸易公司根本不避讳自己是贸易公司,外国人也不在乎。他们更关心的是贸易公司能否妥善安…...
c++重中之重:“换个龟壳继续套娃“:运算符重载等的学习
文章目录 前言一.运算符重载二.const成员三.取地址重载总结前言 上一期我们讲到类的6个默认构造函数中的拷贝构造函数,这一期我们继续往下讲,当然难点肯定是运算符重载了。 一、运算符重载 运算符重载是c为了增强代码的可读性引入了运算符重载…...
RabbitMQ简单使用
这篇文章通过一个最简单的例子,让初学者能了解RabbitMQ如何完成生产消息和消息的。 所有的程序员在学习一门新技术的时候,都是从 Hello World 进入到Colorful World的,本节也将按照惯例,从HelloWorld开始,演示RabbitMQ…...
江苏企业网站建设公司/seo职业培训学校
一、值类型(基本类型): 数值型: 十进制:0~9 八进制:0~7 十六进制:0X、0x 浮点型数据:传统记数(1.2),科学记数(6e3) 特殊值Infinity:超出所表示的…...
wejianzhan是什么网站/如何学会推广和营销
MySQL架构 连接器连接池,安全认证、线程池、连接限制、检查内存、缓存SQL接口 DML、DDLSQL解析器,对SQL语句的权限检查、解析为二进制程序优化器,优化访问路径缓存cache,buffer存储引擎 innodb文件系统日志存储过程 存储过程把经常使用的SQL语…...
dede网站后台打不开/企业关键词大全
request作用域单个请求之间 session作用域打开浏览器,关闭浏览器之间,浏览器相关,同一个用户访问网站的次数 application对象作用域:服务器启动,关闭之间,一个网站被不同用户访问的次数 pageContext作用域&…...
网站购物车作用/手机网站建设平台
水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),水仙花数是指一个 n 位数&#…...
越秀区网站建设公司/广州关键词seo
1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表…...
营销型网站建设需要多少钱/深圳防疫措施优化
获取当前文件夹下的所有空文件夹路径信息 1usingSystem;2usingSystem.Drawing;3usingSystem.Collections;4usingSystem.ComponentModel;5usingSystem.Windows.Forms;6usingSystem.Data;7usingSystem.IO;89namespace删除空文件夹10{ 11 /**//// <summary> 12 /// Fo…...