APUE信号-程序汇总

     近期重看APUE,发现对于非常多程序的要领还是没有全然理解。所以梳理下便于查看,并且有非常多值得思考的问题。


程序清单10- 1  捕获 SIGUSR1 和 SIGUSR2的简单程序
#include "util.h"

static void sig_usr(int);

int
main(void){
if(signal(SIGUSR1,sig_usr) == SIG_ERR)
err_sys("cannot catch SIGUSR1!");
if(signal(SIGUSR2,sig_usr) == SIG_ERR)
err_sys("cannot catch SIGUSR2!");
for(;;)
pause();
} static void sig_usr(int signo){
if(signo == SIGUSR1)
printf("received SIGUSR1\n");
else if(signo == SIGUSR2)
printf("received SIGUSR2\n");
else err_dump("received signal %d\n",signo);
}


程序清单10- 2  在信号处理程序中调用不可重入函数
#include "util.h"
#include <pwd.h> static void
my_alarm(int signo){
struct passwd*rootptr;
printf("in signal handler\n");
if ((rootptr = getpwnam("de15")) == NULL)
err_sys("getpwnam(de15) error");
alarm(1);
} int
main(void){
struct passwd*ptr; signal(SIGALRM, my_alarm);
alarm(1);
for ( ; ; ) {
if ((ptr = getpwnam("vonzhou")) == NULL)
err_sys("getpwnam error");
if (strcmp(ptr->pw_name, "vonzhou") != 0)
printf("return value corrupted!, pw_name = %s\n", ptr->pw_name);
}
}


程序清单10- 3  SIGCLD处理程序(在Linux下等价于SIGCHLD)
#include"util.h"
#include<sys/wait.h> static void sig_cld(int); int
main()
{
pid_t pid;
if (signal(SIGCLD, sig_cld) == SIG_ERR)
perror("signal error");
if ((pid = fork()) < 0) {
perror("fork error");
} else if (pid == 0) {/* child */
sleep(2);
_exit(0);
} pause();/* parent */
exit(0);
} static void
sig_cld(int signo)/* interrupts pause() */
{
pid_t pid;
int status; printf("SIGCLD received\n");
if (signal(SIGCLD, sig_cld) == SIG_ERR)/* reestablish handler */
perror("signal error" );
if ((pid = wait(&status)) < 0)/* fetch child status */
perror("wait error");
printf("pid = %d\n", pid);
}


程序清单10- 4  sleep 的简单而不完整的实现
#include<signal.h>
#include<unistd.h> /**存在的问题是。可能在一个繁忙的系统中调用pause之前超时,
* 直接调用信号处理程序。pause后假设没有捕捉到其它信号,
* 该程序将永远被挂起
*/
static void
sig_alrm(int signo)
{
/* nothing to d o, just return to wake up the pause */
} unsigned int
sleep1(unsigned int nsecs)
{
if (signal(SIGALRM, sig_alrm) == SIG_ERR)
return(nsecs);
alarm(nsecs);/* start the timer */
pause();/* next caught signal wakes us up */
return(alarm(0));/* turn off timer, return unslept time */
}


程序清单10- 5  sleep 的还有一个(不完好)实现
#include<setjmp.h>
#include<signal.h>
#include<unistd.h> static jmp_buf env_alrm; static void
sig_alrm(int signo)
{
longjmp(env_alrm, 1);
} unsigned int
sleep2(unsigned int nsecs)
{
if (signal(SIGALRM, sig_alrm) == SIG_ERR)
return(nsecs);
if(setjmp(env_alrm) == 0){
alarm(nsecs);/* start the timer */
pause();/* next caught signal wakes us up */
} return(alarm(0));/* turn off timer, return unslept time */
}


程序清单10- 6  在一个捕获其它信号的程序中调用sleep2
#include "util.h"

unsigned int sleep2(unsigned int);
static void sig_int(int); int
main(void)
{
unsigned int unslept;
if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
unslept = sleep2(5);
printf("sleep2 returned: %u\n", unslept);
exit(0);
} static void
sig_int(int signo)
{
int i, j;
volatile int k;
/*
* Tune these loops to run for more than 5 seconds
* on whatever system this test program is run.
*/
printf("\nsig_int starting\n");
for (i = 0; i < 300000; i++)
for (j = 0; j < 4000; j++)
k += i * j;
printf("sig_int finished\n");
}
/*
vonzhou@de15:~/Coding/apue/signals$ ./a.out
^C
sig_int starting
sleep2 returned: 0
vonzhou@de15:~/Coding/apue/signals$
*/


程序清单10- 7  具有超时限制的read调用
#include "util.h"

static void sig_alrm(int);

int
main(void)
{
int n;
char line[MAXLINE];
if (signal(SIGALRM, sig_alrm) == SIG_ERR)
err_sys("signal(SIGALRM) error");
alarm(10);
if ((n = read(STDIN_FILENO, line, MAXLINE)) < 0)
err_sys("read error");
alarm(0);
write(STDOUT_FILENO, line, n);
exit(0);
} static void
sig_alrm(int signo)
{
/* nothing to do, just return to interrupt the read */
}
/*
vonzhou@de15:~/Coding/apue/signals$ ./a.out
read error: Interrupted system call (假设长时间不输入,则发现系统调用被中断)
vonzhou@de15:~/Coding/apue/signals$ ./a.out
oewutjowerjtlewrt
oewutjowerjtlewrt
vonzhou@de15:~/Coding/apue/signals$
*/

程序清单10- 8  使用longjmp。带超时限制,调用read
#include "util.h"
#include <setjmp.h> static void sig_alrm(int);
static jmp_buf env_alrm; int
main(void)
{
int n;
char line[MAXLINE];
if (signal(SIGALRM, sig_alrm) == SIG_ERR)
err_sys("signal(SIGALRM) error");
if (setjmp(env_alrm) != 0)
err_quit("read timeout"); alarm(10);
if ((n = read(STDIN_FILENO, line, MAXLINE)) < 0)
err_sys("read error");
alarm(0); write(STDOUT_FILENO, line, n);
exit(0);
} static void
sig_alrm(int signo)
{
longjmp(env_alrm, 1);
}


程序清单10- 9  sigaddset,sigdelset,sigismember的实现(假定信号集合是整型)
#include<signal.h>
#include<errno.h>
/**
* 如果把 sigset_t 视为整数。各种位操作
*/
/* <signal.h> usually defines NSIG to include signa l number 0 */
#define SIGBAD(signo)((signo) <= 0 || (signo) >= NSIG) int sigaddset(sigset_t *set, int signo)
{
if (SIGBAD(signo)) { errno = EINVAL; return(-1); } *set |= 1 << (signo - 1);/* turn bit on */
return(0);
} int
sigdelset(sigset_t *set, int signo)
{
if (SIGBAD(signo)) { errno = EINVAL; return(-1); }
*set &= ~(1 << (signo - 1));/* turn bit off */
retur n(0);
} int
sigismember(const sigset_t *set, int signo)
{
if (SIGBAD(signo)) { errno = EINVAL; return(-1); }
return((*set & (1 << (signo - 1))) != 0);
}

程序清单10-10  为进程打印信号屏蔽字
#include "util.h"
#include<errno.h> void
pr_mask(const char *str){
sigset_t sigset;
int errno_save; errno_save = errno;
if(sigprocmask(0, NULL, &sigset) < 0)
err_sys("sigpromask failed.");
printf("%s",str);
if(sigismember(&sigset, SIGINT))
printf("SIGINT ");
if(sigismember(&sigset, SIGQUIT))
printf("SIGQUIT ");
if(sigismember(&sigset, SIGUSR1))
printf("SIGUSR1 ");
if(sigismember(&sigset, SIGALRM))
printf("SIGARM "); //remaining signals can get here.
printf("\n");
errno = errno_save;
}

程序清单10-11  信号设置和 sigpromask 实例
#include "util.h"

static void sig_quit(int);

int
main(void)
{
sigset_t newmask, oldmask, pendmask;
if (signal(SIGQUIT, sig_quit) == SIG_ERR)
err_sys("can't catch SIGQUIT");
/*
* Block SIGQUIT and save current signal mask.
*/
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error"); sleep(5);/* SIGQUIT here will remain pending */ if (sigpending(&pendmask) < 0)
err_sys("sigpending error");
if (sigismember(&pendmask, SIGQUIT))
printf("\nSIGQUIT pending\n"); /*
* Reset signal mask which unblocks SIGQUIT.
*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
printf("SIGQUIT unblocked\n"); sleep(5);/* SIGQUIT here will terminate with core file */
exit(0);
} static void
sig_quit(int signo)
{
printf("caught SIGQUIT\n");
if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
err_sys("can't reset SIGQUIT");
}

程序清单10-12  用 sigaction 实现的 signal 函数
#include "util.h"
// Reliable version of signal(),using POSIX sigaction;
Sigfunc *signal(int signo,Sigfunc *func){
struct sigaction act,oact; act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(signo == SIGALRM){
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
}else{
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART;
#endif
}
if(sigaction(signo,&act,&oact)<0)
return(SIG_ERR);
return(oact.sa_handler);
}


程序清单10-13  阻止不论什么被中断系统调用重新启动动的的 signal 函数
#include "util.h"

// will stop all the inttrupted signal,that is sigaction's
//default behavior ,so deal with the early aspects;
Sigfunc *
signal_intr(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0; #ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
if (sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}

程序清单10-14  信号屏蔽字,sigsetjmp。siglongjmp 实例
#include "util.h"
#include<setjmp.h>
#include<time.h> static void sig_usr(int),sig_alrm(int);
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjmp; int
main(void){
if(signal(SIGUSR1,sig_usr) == SIG_ERR)
err_sys("register signal SIGUSR1 error");
if(signal(SIGALRM,sig_alrm) == SIG_ERR)
err_sys("register signal SIGALRM error"); pr_mask("starting main:"); if(sigsetjmp(jmpbuf,1)){
pr_mask("ending main:");
exit(0);
} canjmp = 1;// now sigsetjmp is ok ,can jmp there
for(;;)
pause();
} static void
sig_usr(int signo){
time_t starttime;
if(canjmp == 0)
return;//not prepare well,so ignore it ;
pr_mask("starting sig_usr:");
alarm(3); // SIGALRM in 3 sec
starttime = time(NULL);
for(;;)
if(time(NULL) > starttime + 5)
break;
pr_mask("ending sig_usr:"); canjmp = 0;
siglongjmp(jmpbuf,1);
} static void
sig_alrm(int signo){
pr_mask("in sig_alrm:");
}

程序清单10-15  保护临界区不被信号中断
#include "util.h"

static void sig_int(int);

int
main(void)
{
sigset_t newmask, oldmask, waitmask;
pr_mask("program start: ");
if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
sigemptyset(&waitmask);
sigaddset(&waitmask, SIGUSR1);
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
/*
* Block SIGINT and save current signal mask.
* */
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");
/*
* Critical region of code.
*/
pr_mask("in critical region: ");
/*
* * Pause, allowing all signals except SIGUSR1.
*/
if (sigsuspend(&waitmask) != -1)
err_sys("sigsuspend error");
pr_mask("after return from sigsuspend: ");
/*
* Reset signal mask which unblocks SIGINT.
*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error"); /*
* And continue processing ...
*/
pr_mask("program exit: "); exit(0);
} static void
sig_int(int signo)
{
pr_mask("\nin sig_int: ");
}

程序清单10-16  用sigsuspend等待一个全局变量被设置
#include "util.h"

volatile sig_atomic_t	quitflag;	/* set nonzero by signal handler */

static void
sig_int(int signo) /* one signal handler for SIGINT and SIGQUIT */
{
if (signo == SIGINT)
printf("\ninterrupt\n");
else if (signo == SIGQUIT)
quitflag = 1; /* set flag for main loop */
} int
main(void)
{
sigset_t newmask, oldmask, zeromask; if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
if (signal(SIGQUIT, sig_int) == SIG_ERR)
err_sys("signal(SIGQUIT) error"); sigemptyset(&zeromask);
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT); /*
* Block SIGQUIT and save current signal mask.
*/
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error"); while (quitflag == 0)
sigsuspend(&zeromask);
// suspend will use zeromask to replace the new mask , this is to say ,
//here we temporarily change the signal mask, can catch any signal ;
/*
* SIGQUIT has been caught and is now blocked; do whatever.
*/
quitflag = 0; /*
* Reset signal mask which unblocks SIGQUIT.
*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error"); exit(0);
}

程序清单10-17  父子进程能够用来实现同步的例程(TELL_WAIT)
#include "util.h"

static volatile sig_atomic_t sigflag; 	/* set nonzero by sig handler */
static sigset_t newmask, oldmask, zeromask; static void sig_usr(int signo) /* one signal handler for SIGUSR1 and SIGUSR2 */
{
sigflag = 1;
} void TELL_WAIT(void)
{
if (signal(SIGUSR1, sig_usr) == SIG_ERR)
err_sys("signal(SIGUSR1) error");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)
err_sys("signal(SIGUSR2) error");
sigemptyset(&zeromask);
sigemptyset(&newmask);
sigaddset(&newmask, SIGUSR1);
sigaddset(&newmask, SIGUSR2); /*
* Block SIGUSR1 and SIGUSR2, and save current signal mask.
*/
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");
} void TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we're done */
} void WAIT_PARENT(void)
{
while (sigflag == 0)
sigsuspend(&zeromask); /* and wait for parent */
sigflag = 0; /*
* Reset signal mask to original value.
*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
} void TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1); /* tell child we're done */
} void WAIT_CHILD(void)
{
while (sigflag == 0)
sigsuspend(&zeromask); /* and wait for child */
sigflag = 0; /*
* Reset signal mask to original value.
*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
}

程序清单10-18  abort 的 POSIX.1 实现
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> void
abort(void) /* POSIX-style abort() function */
{
sigset_t mask;
struct sigaction action; /*
* * Caller can't ignore SIGABRT, i f so reset to default.
* * */
sigaction(SIGABRT, NULL, &action);
if (action.sa_handler == SIG_IGN) {
action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &action, NULL);
} if (action.sa_handler == SIG_DFL)
fflush(NULL);/* flush all open stdio streams */
/*
* * * Caller can't block SIGA BRT; make sure it's unblocked.
* * */
sigfillset(&mask);
igdelset(&mask, SIGABRT);/* mask has only SIGABRT turned off */
sigprocmask(SIG_SETMASK, &mask, NULL);
kill(getpid(), SIGABRT);/* send the signal */ /*
* * * If we're here, p rocess caught SIGABRT and returned.
* * */
fflush(NULL);/* flush all open stdio streams */
action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &action, NULL);/* reset to default */
igprocmask(SIG_SETMASK, &mask, NU LL);/* just in case ... */
kill(getpid(), SIGABRT);/* and one mor e time */
exit(1);/* this should never be executed ... */
}

程序清单10-19  用 system 调用 ed 编辑器  
#include "util.h"

static void sig_int(int signo){
printf("Caught SIGINT \n");
}
static void sig_chld(int signo){
printf("Caught SIGCHLD \n");
}
int main(){
if(signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
if(signal(SIGCHLD, sig_chld) == SIG_ERR)
err_sys("signal(SIGCHLD) error"); if(system("/bin/ed") < 0)
err_sys("system(ed) error"); exit(0);
}

程序清单10-20  system 函数的 POSIX.1 正确实现
#include<sys/wait.h>
#include<errno.h>
#include<signal.h>
#include<unistd.h>
#include <stdio.h> int
system( const char *cmdstring)/* with appropriate signal handling */
{
pid_t pid;
int status;
struct sigaction ignore, saveintr, savequit;
sigset_t chldmask, savemask;
if (cmdstring == NULL)
return(1); /* always a command processor with UNIX */ ignore.sa_handler = SIG_IGN;/* ignore SIGINT and SIGQUIT */
sigemptyset(&ignore.sa_mask);
ignore.sa_flags = 0;
if (sigaction(SIGINT, &ignore, &saveintr) < 0)
return(-1);
if (sigaction(SIGQUIT, &ignore, &savequit) < 0)
return(-1);
sigemptyset(&chldmask);/* now block SIGCHLD */
sigaddset(&chldmask, SIGCHLD);
if(sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
return(-1); if ((pid = fork()) < 0) {
status = -1;/* probably out of processes */
} else if (pid == 0) {/* child */
/* restore previous signal actions & reset signal ma sk */
sigaction(SIGINT, &saveintr, NULL);
sigaction(SIGQUIT, &savequit, NULL);
sigprocmask(SIG_SETMASK, &savemask, NULL); execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127);/* exec error */
} else { /* parent */
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR) {
status = -1; /* error other than EINTR from waitpid() */
break;
}
} /* restore previous signal actions & reset signal mask */
if (sigaction(SIGINT, &saveintr, NULL) < 0)
return(-1);
if (sigaction(SIGQUIT, &savequit, NULL) < 0)
return(-1);
printf("before unblock SIGCHLD...\n");
if (sigprocmask(SIG_SETMASK, &savemask, NULL) < 0)
return(-1); return(status);
}

程序清单10-21  sleep 的可靠实现
#include "util.h"

static void
sig_alrm(int signo)
{
/* nothing to do, just returning wakes up sigsuspend() */
} unsigned int
sleep(unsigned int nsecs)
{
struct sigaction newact, oldact;
sigset_t newmask, oldmask, suspmask;
unsigned int unslept; /* set our handler, save previous information */
newact.sa_handler = sig_alrm;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGALRM, &newact, &oldact); /* block SIGALRM and save current signal mask */
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask); alarm(nsecs); suspmask = oldmask;
sigdelset(&suspmask, SIGALRM);/* make sure SIGALRM isn't blocked */
sigsuspend(&suspmask);/* wait for any signal to be caught */ /* some signal has been caught, SIGALRM is now blocked */ unslept = alarm(0);
sigaction(SIGALRM, &oldact, NULL);/* reset previous action */ /* reset signal mask, which unblocks SIGALRM */
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return(unslept);
}



APUE信号-程序汇总的更多相关文章

  1. APUE 线程 - 程序清单

    APUE 线程 - 程序清单 程序清单11-1 打印线程ID #include "util.h" #include<pthread.h> pthread_t ntid; ...

  2. 【C】——APUE小程序之递归遍历目录

    递归降序遍历目录层次结构,并按文件类型计数. 先介绍相关的函数: #include<dirent.h> DIR *opendir(const char *pathname); //打开目录 ...

  3. Java入门的程序汇总

    Java入门的基础程序,虽然很简单,也要多练习,下面有重点的总结一下 1.HelloWorld这个不说了 2.常量与变量部分 基本数据类型使用 public class Javashujuleixin ...

  4. Android L Camera2 API 使用实例程序汇总

    在网上发现几个使用Camera API2开发的实例程序,总结一下方便后续参考: 1.Camera2 Basic : https://github.com/googlesamples/android-C ...

  5. chrome常用扩展程序汇总(程序员版)

    chrome常用扩展程序之程序员版 1.chrome扩展程序 Chrome插件是一个由Web技术开发.用来增强浏览器功能的小程序,其实就是一个由HTML.CSS.JS.图片等静态资源组成的一个.crx ...

  6. linux信号程序编译遇到的问题

    如果把这个去掉-std=c99就会运行通过 还有一点就是 for(int i=0;i<n;i++) 在循环里声明变量仅被用在c99里面.也就是要想在循环里面声明变量,就必须使用-std=c99

  7. APUE学习笔记——10信号——信号接口函数 signal 和 sigaction

    signal函数     signal函数是早起Unix系统的信号接口,早期系统中提供不可靠的信号机制.在后来的分支中,部分系统使用原来的不可靠机制定义signal函数,如 Solaris 10 .而 ...

  8. Linux下对后台进程通过kill传递信号不起作用的问题

    在阅读APUE信号一章时,我遇到Linux下对后台进程通过kill传递信号不起作用的问题 具体情形与如下链接中的老兄一致: http://bbs.csdn.net/topics/390335913?p ...

  9. 1万字!彻底看懂微信小程序

    Q:为什么说小程序如炮友? A:小程序刚发布不久就流行一个段子:APP如原配,一年不用几次:服务号如情人,一个月固定几次:订阅号如酒店小卡片,天天可以卖广告:小程序像炮友,用完就走. 资本如嫖客,各个 ...

随机推荐

  1. 基于matplotlib的数据可视化 - 柱状图bar

    柱状图bar 柱状图常用表现形式为: plt.bar(水平坐标数组,高度数组,宽度比例,ec=勾边色,c=填充色,label=图例标签) 注:当高度值为负数时,柱形向下 1 语法 bar(*args, ...

  2. css浮动中避免包含元素高度为0的4种解决方法

    问题:当子元素中使用了float时,如果其父元素不指定高度,其高度将为0 解决:清除(闭合)浮动元素,使其父div高度自适应 方法一:额外标签+clear:both     (W3C推荐方法,兼容性较 ...

  3. Spring Boot修改内置Tomcat端口号

    spring Boot 内置Tomcat默认端口号为8080,在开发多个应用调试时很不方便,本文介绍了修改 Spring Boot内置Tomcat端口号的方法. 一.EmbeddedServletCo ...

  4. 使用 Apache Commons CSV 读写 CSV 文件

    有时候,我们需要读写 CSV 文件,在这里给大家分享Apache Commons CSV,读写 CSV 文件非常方便. 具体官方文档请访问Apache Commons CSV. 官方文档已经写得很详细 ...

  5. IntelliJ IDEA推荐插件

    JRebel for IntelliJ 一款热部署插件,只要不是修改了项目的配置文件,用它都可以实现热部署.收费的,破解比较麻烦.不过功能确实很强大.算是开发必备神器了.热部署快捷键是control+ ...

  6. ubuntu14.4.4安装smb服务实现文件共享

    1.软件安装,ubuntu14需要安装的软件有3个 安装服务前养成习惯 sudo apt-get upgrade 首先切换到超级用户  su - root sudo apt-get install s ...

  7. django 用户管理系列:1 user

    :first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdow ...

  8. centos 7 执行 groupinstall报错

    报错显示Error: Package: systemtap-devel-3.10-10.el7.armv7hl (base) Requires: kernel-devel 解决方案 wget http ...

  9. php分享二十七:批量插入mysql

    一:思考 1:如果插入的某个字段大于数据库定义的长度了,数据库会怎么处理? 1>如果数据库引擎是myisam,则数据库会截断后插入,不报错 2>如果数据库引擎是innodb,则数据库会报 ...

  10. 使用maven-shade-plugin插件解决spark依赖冲突问题

    依赖冲突:NoSuchMethodError,ClassNotFoundException   当用户应用于Spark本身依赖同一个库时可能会发生依赖冲突,导致程序奔溃.依赖冲突表现为在运行中出现No ...