• <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.信號發送與注冊kill/raise alarm  setitimer  signal
              4.信號的屏蔽sigprocmask  sigemptyset sigfillset ...
              5.信號屏蔽的切換
                  sigpending
                  sigsuspend
                    =pause+
                     指定屏蔽信號
                  pause與sigsuspend都回被信號中斷.
                  中斷的是pause與sigsuspen,不是進程中其他代碼
                  
                  sigsuspend放在sigprocmask環境中思考:
                  5.1.sigsuspend是否影響sigprocmask屏蔽的信號呢?
                     影響.使原來的屏蔽信號全部失效.
                     當sigsuspend返回,恢復原來的屏蔽信號.
                  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);//模擬業務處理時間比較長
                    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);//模擬業務處理時間比較長
                    printf("正在拷貝電影<%d>完畢!\n",i);
                    sigpending(&sigu);
                    if(sigismember(&sigu,SIGINT))
                    {
                        sigsuspend(&sigt);
                    }        
                }
                printf("所有電影拷貝完畢\n",sum);
                sigprocmask(SIG_UNBLOCK,&sigs,0);
                printf("over!\n");
            }
            一.最新版本的信號發送與處理
              sigqueue/sigaction           
            1.思考:信號中斷函數調用中是否被其他信號中斷.          
              信號函數調用中只屏蔽本身信號,不屏蔽其他信號.(signal)
              因為屏蔽本身,所以這過程中的信號打來依然會排隊。(不可靠會壓縮)
            2.怎么保證函數調用中屏蔽指定的信號呢?

              sigaction可以指定處理函數調用的屏蔽信號,所以signal是用sigaction來實現屏蔽本身信號的。(sigaction不會屏蔽本身除非你主動設置)
              
              sigaction在處理信號的時候,接受數據.
             
              sigqueue發送信號的時候,可以發送數據.
              
              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.函數說明     
              使用sigaction/sigqueue有兩個理由.
              3.1.穩定
              3.2.增強功能 : 傳參數
             int sigaction(
                    int sig,//被處理信號
                    const struct sigaction*action,//處理函數及其參數
                    struct sigaction*oldact//返回原來的處理函數結構體
                    )
            返回:
               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發送信號
               2.使用sigaction處理信號,使用sigqueue發送信號
               3.發送信號的同時處理數據   
            二.IPC
              1.基于文件
                1.1.無序文件
                1.1.有序文件
                  1.1.1.管道
                    1.1.1.1.有名
                    1.1.1.2.匿名
                  1.1.2.socket
              2.基于內存
                2.1.無序內存
                  2.1.1.匿名內存
                  2.1.2.共享內存
                2.2.有序內存
                  2.2.1.共享隊列
              3.同步:基于內存IPC應用(共享內存數組)
                信號量/信號燈
                
            三.基于普通文件的IPC
              IPC的技術提出的應用背景.
              進程之間需要同步處理:
              同步需要通信.
              普通文件就是最基本的通信手段. 

            #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技術的問題:
                一個進程改變文件,另外一個進程無法感知.
              解決方案:
                 一個特殊的文件:管道文件

            四.管道文件
              1.創建管道mkfifo
              2.體會管道文件特點
             案例:        
               fifoA       fifoB
               建立管道      
               打開管道   打開管道
               寫數據    讀數據
               關閉管道   關閉管道
               刪除管道
                
             建立管道文件:
               使用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)
            {
                //關閉管道
                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秒寫數據
                    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)
            {
                //關閉管道
                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);
                }    
            }
            總結:
               1.read沒有數據read阻塞,而且read后數據是被刪除
               2.數據有序
               3.打開的描述符號可以讀寫(two-way雙工)
               4.管道文件關閉后,數據不持久.
               5.管道的數據存儲在內核緩沖中.
            五.匿名管道
              發現有名的管道的名字僅僅是內核識別是否返回同一個fd的標示.
              所以當管道名失去表示作用的時候,實際可以不要名字.
                 
              在父子進程之間:打開文件描述后創建進程.
              父子進程都有描述符號. 管道文件沒有價值.
              所以在父子進程中引入一個沒有名字的管道:匿名管道.
              結論:
                匿名管道只能使用在父子進程.

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

            #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("任務完成\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任務完成!\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();
                }
                
            }
            亚洲国产日韩欧美综合久久| 色妞色综合久久夜夜| 久久久久久久综合日本亚洲| www亚洲欲色成人久久精品| 久久精品成人影院| 久久久久se色偷偷亚洲精品av | 久久精品国产欧美日韩99热| 伊人久久久AV老熟妇色| 狠狠色丁香婷综合久久| 亚洲第一永久AV网站久久精品男人的天堂AV | 国产V综合V亚洲欧美久久| 国产精品无码久久综合网| 日韩精品久久无码中文字幕| 国产精品热久久无码av| 人妻精品久久无码区| 亚洲欧美国产日韩综合久久| 精品久久一区二区三区| 人妻少妇久久中文字幕| 合区精品久久久中文字幕一区| 狠色狠色狠狠色综合久久| 日韩人妻无码一区二区三区久久| 久久精品无码一区二区app| 久久99国产精品二区不卡| 国产欧美久久久精品影院| 久久精品国产WWW456C0M| 日韩精品国产自在久久现线拍| 日本欧美久久久久免费播放网 | 亚洲AV无码1区2区久久| 亚洲伊人久久成综合人影院| 狠狠久久综合| 99久久精品国产一区二区蜜芽| 国内精品久久久人妻中文字幕| 99精品久久久久久久婷婷| 亚洲中文字幕伊人久久无码| 国产综合精品久久亚洲| 7国产欧美日韩综合天堂中文久久久久 | 日日狠狠久久偷偷色综合免费| 色综合久久最新中文字幕| 久久国产精品久久国产精品| 国产精品9999久久久久| 久久成人精品视频|