• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0
            回顧:
              1.信號的作用
              2.理解信號:
                 軟中斷
                 可靠與不可靠信號kill -l
              3.信號發(fā)送與注冊kill/raise alarm  setitimer  signal
              4.信號的屏蔽sigprocmask  sigemptyset sigfillset ...
              5.信號屏蔽的切換
                  sigpending
                  sigsuspend
                    =pause+
                     指定屏蔽信號
                  pause與sigsuspend都回被信號中斷.
                  中斷的是pause與sigsuspen,不是進程中其他代碼
                  
                  sigsuspend放在sigprocmask環(huán)境中思考:
                  5.1.sigsuspend是否影響sigprocmask屏蔽的信號呢?
                     影響.使原來的屏蔽信號全部失效.
                     當(dāng)sigsuspend返回,恢復(fù)原來的屏蔽信號.
                  5.2.sigsuspend什么時候使用?
            #include <stdio.h>
            #include <stdlib.h>
            #include <signal.h>
            #include <unistd.h>
            void handle(int s)
            {
                printf("信號干擾!\n");
            }
            main()
            {
                int sum=0;
                int i;
                sigset_t sigs,sigt;
                sigemptyset(&sigs);
                sigemptyset(&sigt);
                
                sigaddset(&sigs,SIGINT);
                //sigfillset(&sigs);
                
                signal(SIGINT,handle);
                
                sigprocmask(SIG_BLOCK,&sigs,0);
                for(i=0;i<10;i++)
                {
                    sum+=i;
                    sleep(5);//模擬業(yè)務(wù)處理時間比較長
                    sigsuspend(&sigt);
                    sleep(5);
                }
                printf("%d\n",sum);
                sigprocmask(SIG_UNBLOCK,&sigs,0);
                printf("over!\n");
            }

            #include <stdio.h>
            #include <stdlib.h>
            #include <signal.h>
            #include <unistd.h>
            void handle(int s)
            {
                printf("外部用戶中斷處理!\n");
                sleep(3);
                printf("外部用戶中斷處理完畢!\n");
            }
            main()
            {
                int sum=0;
                int i;
                sigset_t sigs,sigt,sigu;
                sigemptyset(&sigs);
                sigemptyset(&sigt);
                sigemptyset(&sigu);
                
                sigaddset(&sigs,SIGINT);
                //sigfillset(&sigs);
                
                signal(SIGINT,handle);
                
                sigprocmask(SIG_BLOCK,&sigs,0);
                for(i=0;i<10;i++)
                {            
                    printf("正在拷貝電影<%d>!\n",i);
                    sleep(5);//模擬業(yè)務(wù)處理時間比較長
                    printf("正在拷貝電影<%d>完畢!\n",i);
                    sigpending(&sigu);
                    if(sigismember(&sigu,SIGINT))
                    {
                        sigsuspend(&sigt);
                    }        
                }
                printf("所有電影拷貝完畢\n",sum);
                sigprocmask(SIG_UNBLOCK,&sigs,0);
                printf("over!\n");
            }
            一.最新版本的信號發(fā)送與處理
              sigqueue/sigaction           
            1.思考:信號中斷函數(shù)調(diào)用中是否被其他信號中斷.          
              信號函數(shù)調(diào)用中只屏蔽本身信號,不屏蔽其他信號.(signal)
              因為屏蔽本身,所以這過程中的信號打來依然會排隊。(不可靠會壓縮)
            2.怎么保證函數(shù)調(diào)用中屏蔽指定的信號呢?

              sigaction可以指定處理函數(shù)調(diào)用的屏蔽信號,所以signal是用sigaction來實現(xiàn)屏蔽本身信號的。(sigaction不會屏蔽本身除非你主動設(shè)置)
              
              sigaction在處理信號的時候,接受數(shù)據(jù).
             
              sigqueue發(fā)送信號的時候,可以發(fā)送數(shù)據(jù).
              
              sigaction/sigqueue是signal/kill的增強版本

            #include <stdio.h>
            #include <signal.h>
            #include <unistd.h>
            main()
            {
                union sigval val;
                val.sival_int=8888;
                
                sigqueue(3972,SIGUSR1,val);
            }
            3.函數(shù)說明     
              使用sigaction/sigqueue有兩個理由.
              3.1.穩(wěn)定
              3.2.增強功能 : 傳參數(shù)
             int sigaction(
                    int sig,//被處理信號
                    const struct sigaction*action,//處理函數(shù)及其參數(shù)
                    struct sigaction*oldact//返回原來的處理函數(shù)結(jié)構(gòu)體
                    )
            返回:
               0:成功
               -1:失敗
            struct sigaction
                {
                    void (*sa_handle)(int);
                    void (*sa_sigaction)(int,siginfo_t*,void*);
                    sigset_t *mask;//屏蔽信號
                    int flags;//SA_SIGINFO
                    void**//保留成員.
                } 

            #include <stdio.h>
            #include <signal.h>

            #include <unistd.h>
            /*
            void handle(int s)
            {
                printf("OOOK!\n");
                sleep(5);
                printf("K000!\n");
            }
            */
            void handle(int s,siginfo_t* info,void *d)
            {
                printf("OOOK:%d\n",info->si_int);
                sleep(5);
                printf("K000!\n");
            }

            main()
            {
                struct sigaction act={0};
                    
                //act.sa_handler=handle;
                act.sa_sigaction=handle;
                sigemptyset(&act.sa_mask);
                sigaddset(&act.sa_mask,SIGINT);
                
                act.sa_flags=SA_SIGINFO;
                
                sigaction(SIGUSR1,&act,0);
                
                while(1);    
            }
            案例:
               1.使用sigaction處理信號,使用kill發(fā)送信號
               2.使用sigaction處理信號,使用sigqueue發(fā)送信號
               3.發(fā)送信號的同時處理數(shù)據(jù)   
            二.IPC
              1.基于文件
                1.1.無序文件
                1.1.有序文件
                  1.1.1.管道
                    1.1.1.1.有名
                    1.1.1.2.匿名
                  1.1.2.socket
              2.基于內(nèi)存
                2.1.無序內(nèi)存
                  2.1.1.匿名內(nèi)存
                  2.1.2.共享內(nèi)存
                2.2.有序內(nèi)存
                  2.2.1.共享隊列
              3.同步:基于內(nèi)存IPC應(yīng)用(共享內(nèi)存數(shù)組)
                信號量/信號燈
                
            三.基于普通文件的IPC
              IPC的技術(shù)提出的應(yīng)用背景.
              進程之間需要同步處理:
              同步需要通信.
              普通文件就是最基本的通信手段. 

            #include <stdio.h>
            #include <fcntl.h>
            #include <sys/mman.h>
            main()
            {
                int *p;
                int fd;
                int i;
                fd=open("tmp",O_RDWR|O_CREAT,0666);
                ftruncate(fd,4);
                p=mmap(0,4,PROT_READ|PROT_WRITE,
                        MAP_SHARED,fd,0);
                i=0;        
                while(1)
                {
                    sleep(1);
                    *p=i;
                    i++;
                }
                close(fd);
            }

            #include <stdio.h>
            #include <fcntl.h>
            #include <sys/mman.h>
            main()
            {
                int *p;
                int fd;    
                fd=open("tmp",O_RDWR);    
                p=mmap(0,4,PROT_READ|PROT_WRITE,
                        MAP_SHARED,fd,0);
                while(1)
                {
                    sleep(1);
                    printf("%d\n",*p);
                }
                close(fd);
            }

            普通文件IPC技術(shù)的問題:
                一個進程改變文件,另外一個進程無法感知.
              解決方案:
                 一個特殊的文件:管道文件

            四.管道文件
              1.創(chuàng)建管道m(xù)kfifo
              2.體會管道文件特點
             案例:        
               fifoA       fifoB
               建立管道      
               打開管道   打開管道
               寫數(shù)據(jù)    讀數(shù)據(jù)
               關(guān)閉管道   關(guān)閉管道
               刪除管道
                
             建立管道文件:
               使用linux的指令mkfifo


            #include <stdio.h>
            #include <fcntl.h>
            #include <unistd.h>
            #include <sys/stat.h>
            #include <signal.h>
            #include <stdlib.h>
            int fd;
            int i;
            void  end(int s)
            {
                //關(guān)閉管道
                close(fd);        
                //刪除管道
                unlink("my.pipe");
                exit(-1);


            main()
            {
                signal(SIGINT,end);    
                //建立管道
                mkfifo("my.pipe",0666);
                //打開管道
                fd=open("my.pipe",O_RDWR);
                //shutdown(fd,SHUT_RD);
                i=0;
                while(1)
                {
                    //每隔1秒寫數(shù)據(jù)
                    sleep(1);
                    write(fd,&i,4);
                    i++;
                }
                
            }

            #include <stdio.h>
            #include <fcntl.h>
            #include <unistd.h>
            #include <sys/stat.h>
            #include <signal.h>
            #include <stdlib.h>
            int fd;
            void end(int s)
            {
                //關(guān)閉管道
                close(fd);
                exit(-1);
            }
            main()
            {
                int i;    
                //打開管道
                signal(SIGINT,end);
                fd=open("my.pipe",O_RDWR);
                //shutdown(fd,SHUT_WR);
                while(1)
                {
                    read(fd,&i,4);
                    printf("%d\n",i);
                }    
            }
            總結(jié):
               1.read沒有數(shù)據(jù)read阻塞,而且read后數(shù)據(jù)是被刪除
               2.數(shù)據(jù)有序
               3.打開的描述符號可以讀寫(two-way雙工)
               4.管道文件關(guān)閉后,數(shù)據(jù)不持久.
               5.管道的數(shù)據(jù)存儲在內(nèi)核緩沖中.
            五.匿名管道
              發(fā)現(xiàn)有名的管道的名字僅僅是內(nèi)核識別是否返回同一個fd的標(biāo)示.
              所以當(dāng)管道名失去表示作用的時候,實際可以不要名字.
                 
              在父子進程之間:打開文件描述后創(chuàng)建進程.
              父子進程都有描述符號. 管道文件沒有價值.
              所以在父子進程中引入一個沒有名字的管道:匿名管道.
              結(jié)論:
                匿名管道只能使用在父子進程.

            #include <unistd.h>
            #include <stdio.h>
            #include <stdlib.h>
            main()
            {
                int fd[2];
                pipe(fd);
                if(fork())
                {//parent
                    close(fd[0]);//只負責(zé)寫
                    while(1)
                    {
                        write(fd[1],"Hello",5);
                        sleep(1);
                    }
                }
                else
                {//child
                    char buf[20];
                    int r;
                    close(fd[1]);//只負責(zé)讀
                    while(1)
                    {
                        r=read(fd[0],buf,20);
                        buf[r]=0;
                        printf("::%s\n",buf);
                    }
                }
            }
             1.創(chuàng)建匿名管道
              2.使用匿名管道
            案例:
              匿名管道的創(chuàng)建
              體會匿名管道的特點
              int pipe(int fd[2]);//創(chuàng)建管道.打開管道.拷貝管道.關(guān)閉讀寫  
              fd[0]:只讀(不能寫)
              fd[1]:只寫(不能讀) 
              
              注意:數(shù)據(jù)無邊界.
              
            綜合:
              建立兩個子進程:
               一個負責(zé)計算1-5000的素數(shù)
               另外一個負責(zé)計算5001-10000
               父進程負責(zé)存儲

            #include <stdio.h>
            #include <unistd.h>
            #include <fcntl.h>
            #include <signal.h>
            #include <stdlib.h>
            #include <string.h>
            #include <sched.h>
            int idx=0;
            int fddata;
            void handle(int s)
            {
                int status;
                if(s==SIGCHLD)
                {
                    wait(&status);        
                    idx++;
                    if(idx==2)
                    {
                        close(fddata);
                        printf("任務(wù)完成\n");
                        exit(-1);
                    }
                }
            }
            int isprimer(int ta)
            {
                int i=2;
                for(;i<ta;i++)
                {
                    if(ta%i==0)
                    {
                        return 0;
                    }
                }
                return 1;
            }
            main()
            {
                int a,b;
                int id=1;
                int fd[2];
                signal(SIGCHLD,handle);
                pipe(fd);
                while(1)
                {
                    if(id==1){
                        a=2;b=50000;
                    }
                    if(id==2){
                        a=50001;b=100000;
                    }
                    if(fork()){            
                        id++;
                        if(id>2){
                            break;
                        }
                        continue;
                    }
                    else{
                        //子進程
                        int i;
                        close(fd[0]);
                        for(i=a;i<=b;i++)
                        {
                            if(isprimer(i))
                            {
                                write(fd[1],&i,sizeof(int));
                            }
                            sched_yield();                
                        }
                        printf("%d任務(wù)完成!\n",getpid());
                        exit(0);
                    }
                }
                int re;
                char buf[20];
                //打開文件,準備存儲
                close(fd[1]);
                fddata=open("result.txt",
                        O_RDWR|O_CREAT,0666);
                while(1)
                {            
                    read(fd[0],&re,sizeof(int));
                    sprintf(buf,"%d\n",re);
                    write(fddata,buf,strlen(buf));
                    sched_yield();
                }
                
            }
            国产69精品久久久久777| 久久无码国产专区精品| 久久99精品久久久久子伦| 狠狠88综合久久久久综合网 | 日本福利片国产午夜久久| 亚洲成人精品久久| 久久笫一福利免费导航 | 久久笫一福利免费导航 | 国产精品女同一区二区久久| 久久久这里只有精品加勒比| 久久这里只精品国产99热| 久久精品国产99国产精品亚洲| 久久96国产精品久久久| 久久这里只有精品首页| 99久久婷婷免费国产综合精品| 亚洲国产日韩欧美久久| 办公室久久精品| 人妻精品久久久久中文字幕一冢本| 久久WWW免费人成—看片| 久久国产免费观看精品3| 伊人情人综合成人久久网小说 | 久久久精品久久久久特色影视| 久久亚洲私人国产精品| 中文精品99久久国产 | 精品99久久aaa一级毛片| 久久久久久午夜成人影院| 久久99热这里只频精品6| 精品久久久久久无码人妻热| 99麻豆久久久国产精品免费| 色欲久久久天天天综合网精品| 久久免费视频1| 国产精品中文久久久久久久| 亚洲欧美一区二区三区久久| 婷婷久久综合九色综合九七| 久久精品无码av| 日本加勒比久久精品| 久久亚洲国产成人影院| 久久AV高潮AV无码AV| 性欧美丰满熟妇XXXX性久久久| 午夜不卡久久精品无码免费| 精品久久久久久国产|