• linux系统调用函数---12


    Linux应用编程学习笔记

                                    周学伟

    一.系统调用文件编程

     

    1.文件打开函数

     /*****************************************************************************

      函数名:open

      函数原型:int open(const char * pathname, int flags)

                int open(const char * pathname,int  flags,mode_t  mode)

      函数功能:打开或创建一个文件

      所属头文件:<sys/types.h>  <sys/stat.h>  <fcntl.h>

      返回值:成功时:返回的是文件描述符

              失败时:返回-1

      参数说明:pathname:打开文件的路径与文件名

                Flags:打开方式

                    O_RDONLY:只读方式打开

                    O_WRONLY:只写方式打开

                    O_RDWE:读写模式

                    还有附加选项,选项通过”|”与上面链接

                    O_APPEND:每次写操作都写入文件的尾部

                    O_CREAT:如果指定文件不存在,则创建这个文件

                Mode:前提是前面使用O_CREAT参数,创建这个文件并且以mode模式打开

    ****************************************************************************/

    2.创建文件

     /*****************************************************************************

      函数名:creat

      函数原型:int creat(const char * pathname,mode_t mode)

      函数功能:创建一个文见并以只写的方式打开该文件

      所属头文件:<sys/types.h>  <sys/stat.h>  <fcntl.h>

      返回值:成功时:返回的是文件描述符

              失败时:返回-1

      参数说明:pathname:创建的文件的路径与文件名

                Flags:创建文件读写权限

                    O_RDONLY:只读方式打开

                    O_WRONLY:只写方式打开

                    O_RDWE:读写模式

                    还有附加选项,选项通过”|”与上面链接

                    O_APPEND:每次写操作都写入文件的尾部

                    O_CREAT:如果指定文件不存在,则创建这个文件

                Mode:前提是前面使用O_CREAT参数,创建这个文件并且以mode模式打开

    ****************************************************************************/

    3.关闭文件

     /*****************************************************************************

      函数名:close

      函数原型:int close(int fd)

      函数功能:创建一个文件并以只写的方式打开该文件

      所属头文件:  <unistd.h>

      返回值:成功时:返回0

              失败时:返回-1

      参数说明:fd:关闭文件的文件描述符

    ****************************************************************************/

    4.读文件

     /*****************************************************************************

      函数名: read

      函数原型:ssize_t read(int fd,void *buf,size_t count)

      函数功能:读文件

      所属头文件:  <unistd.h>

      返回值:成功时:返回读取的字节数

              失败时:返回-1

      参数说明:fd:要进行读操作的文件的文件描述符

                buf:存储从fd所指向的文件中读取的数据

                count:希望读取的字节数

    ****************************************************************************/

    4.写文件

     /*****************************************************************************

      函数名:write

      函数原型:ssize_t write(int fd,const void *buf,size_t ledgth)

      函数功能:想指定文件写入数据

      所属头文件:  <unistd.h>

      返回值:成功时:返回写入到文件中的的字节数

              失败时:返回-1

      参数说明:fd:要进行读操作的文件的文件描述符

                buf:要写入数据的存放区

                ledgth:希望写入的字节数

    ****************************************************************************/

     

    5.文件定位

     /*****************************************************************************

      函数名:lseek

      函数原型:off_t lseek(int fd,0ff_t offset int whence)

      函数功能:重新定位文件的读写位置

      所属头文件:  <sys/types.h>  <unistd.h>

      返回值:成功时:返回移动后的文件指针距离文件头的位置

              失败时:返回-1

      参数说明:fd:要进行操作的文件的文件描述符

                Offset:从whence所指的位置开始向前或向后移动Offset个偏移量

                whence:文件指针起始位置。取值如下:

                       SEEK_SET:文件指针起始位置在文件头部

                       SEEK_CUR:文件指针起始位置在文件当前位置

                       SEEK_END:文件指针起始位置在文件尾部

    ****************************************************************************/

    6.复制文件的描述符

    /*****************************************************************************

      函数名:dup

      函数原型:int dup(int oldfd)

      函数功能:复制文件描述符

      所属头文件:  <unistd.h>

      返回值:成功时:返回新的文件描述符

              失败时:返回-1

      参数说明:oldfd:待复制的老的文件描述符

    ****************************************************************************/

    文件说明:文件拷贝函数

    创建日期:2014.11.25

    创建者:周学伟

    函数说明:./text start.S cpdfile

    -----------------------------------------------------------------------------------------------------------------

    #include <sys/types.h> 

    #include <sys/stat.h> 

    #include <unistd.h> 

    #include <fcntl.h>

    void main(int argc, char ** argv)

    {

       int fd_s,fd_d;

       char buf[512];

       int count = 0;

       /***打开源文件***/

       fd_s =  open(argv[1],O_RDONLY);

       /***打开或创建目标文件***/

       fd_d = open(argv[2],O_RDWR|O_CREAT,0666);

       /***循环读取所有内容***/

       while((count = read(fd_s,buf,512))>0)

         {  

              write(fd_d,buf,count);

         }

       close(fd_s);

       close(fd_d);   

    }

    二.库函数访问文件编程

      1.打开文件

     /*****************************************************************************

      函数名:fopen

      函数原型:FILE * fopen(const char * path,const char * mode) 

      函数功能:打开文件

      所属头文件:  <stdio.h> 

      返回值:成功时:返回文件的指针

              失败时:返回空指针NULL

      参数说明:path:文件的名字,包含路径

                Mode:打开方式,参数如下:

                       “r”:以只读方式打开文件

                       “r+”:以可读可写方式打开文件

                       “w”:以只写方式打开文件,若文件不存在则创建该文件

                       “w+”::以可读可写方式打开文件,若文件不存在则创建该文件否则                                             文件会被清空

                       “a”:以追加方式打开只写文件,若文件不存在则创建该文件,若文件               

             存在写入的数据会追加到文件尾部。原先文件内容会被保存

             “a”:以追加方式打开可读可写文件,若文件不存在则创建该文件,    

    ****************************************************************************/

    2.关闭文件

     /*****************************************************************************

      函数名:fclose

      函数原型:int fclose(FILE *fp )

      函数功能:关闭打开的文件

      所属头文件:  <stdio.h>

      返回值:成功时:返回0

              失败时:返回EOF

      参数说明:fp:关闭fp指向指向的文件的指针

    ****************************************************************************/

    3.读文件

     /*****************************************************************************

      函数名:fread

      函数原型:size_t fread(void *ptr.size _t size,size_t named,FILE * stream)

      函数功能:从文件中读取数据

      所属头文件:  <stdio.h>

      返回值:成功时:返回成功读取到的数据量

              失败时:返回0

      参数说明:stream:指向要读取数据的文件

                   Ptr:指向读取到的数据存放的位置

                  Size:每块数据中每次读取的数据大小Size

                Named:读取Named块数据

    ****************************************************************************/

    4.写文件

     /*****************************************************************************

      函数名:fwrite

      函数原型:size_t fwrite  (const void *buffer .size _t size,size_t named,FILE * stream)

      函数功能:向文件中写入数据

      所属头文件:  <stdio.h>

      返回值:成功时:返回成功写入到的数据量

              失败时:返回0

      参数说明:stream:指向要写入数据的文件

                buffer:存放要写入文件的数据

                 Size:每块数据中每次写入的数据大小Size

               Named:写入Named块数据

    ****************************************************************************/

    5.定位文件

     /*****************************************************************************

      函数名:fseek

      函数原型:size_t fseek  (FILE * stream,long offset,int origin)

      函数功能:重新定位文件的读写位置

      所属头文件:  <stdio.h>

      返回值:成功时:返回0

              失败时:返回-1

      参数说明:stream:指向要写入数据的文件

                Offset:偏移量,正数表示正向移动,复数表示负向移动

                Origin:文件指针起始位置。取值如下:

                       SEEK_SET:文件指针起始位置在文件头部

                       SEEK_CUR:文件指针起始位置在文件当前位置

                       SEEK_END:文件指针起始位置在文件尾部

                      (可用数字一次表示为:0, 1, 2

    ****************************************************************************/

    三.时间编程

    4.获取日历时间

    /*****************************************************************************

      函数名:time

      函数原型:time_t time (time_t * time)

      函数功能:获取当前的系统时间

      所属头文件:  <time.h>

      返回值:成功时:返回日历时间(秒数)

              失败时:返回-1

      参数说明:time:不为空的情况下,保存从1970.1.1.0点0分0秒到现在的秒数

    ****************************************************************************/

    5.获取格林威治时间

    /*****************************************************************************

      函数名:gmtime

      函数原型:struct tm *gmtime (const time_t *clock)

      函数功能:通过日历时间转化成格林威治时间(世界标准时间)

      所属头文件:  <time.h>

      返回值:成功时:返回世界标准时间,以struct tm 结构返回

              失败时:返回NULL

      参数说明:clock:待转化的时间

    ****************************************************************************/

    6.获取本地时间

    /*****************************************************************************

      函数名:localtime

      函数原型:struct tm *localtime (const time_t *clock)

      函数功能:获取本地时间

      所属头文件:  <time.h>

      返回值:成功时:返回本地时间,返回值以struct tm结构返回

              失败时:返回NULL

      参数说明:clock:指向待转化的日历时间的指针变量

    ****************************************************************************/

    7.以字符串格式本地时间

    /*****************************************************************************

      函数名:asctime

      函数原型:char *ascltime (const struvt tmt *clock)

      函数功能:把tm格式存放的时间转化为字符串格式

      所属头文件:  <time.h>

      返回值:成功时:返回字符串格式的时间

              失败时:返回NULL

      参数说明:clock:待转化的tm格式的时间

    ****************************************************************************/

    8获取高精度的时间

    /*****************************************************************************

      函数名:gettimeofday

      函数原型:int gettimeofday(struct timeval *tv, struct timezone *tz)

      函数功能:获取到本地高精度的时间

      所属头文件:<sys/time.h>

      返回值:成功时:返回0

              失败时:返回-1

      参数说明:tv:指向包含秒和微妙的结构(从1970.1.1.0点0分0秒到现在)

                tz:通常为空NULL

    ****************************************************************************/

    四.进程控制理论

    1.获取进程的PID

    /*****************************************************************************

      函数名:getpid

      函数原型:pid_t getpid(void)

      函数功能:获取调用getpid的进程的PID

      所属头文件:<unistd.h>  <sys/types.h>

      返回值:成功时:返回调用进程的ID

      参数说明:无

    ****************************************************************************/

    2.创建一个子进程

    /*****************************************************************************

      函数名:fork

      函数原型:pid_t fork(void)

      特殊说明:1.运行次序不一定

                2.子进程拥有自己独立的栈区

                3.子进程只能用exit()函数退出,父进程可用exit()函数也可用return退出

      函数功能:创建一个子进程

      所属头文件:<unistd.h> 

      返回值:成功时:子进程中:返回0

                      父进程中:返回子进程的ID

              失败时:返回-1

      参数说明:无

    ****************************************************************************/

    3.创建一个子进程

    /*****************************************************************************

      函数名:vfork

      函数原型:pid_t vfork(void)

      特殊说明:1.一定是子进程先运行。

                2.子进程和父进程共享同一片栈区

                3.子进程只能用exit()函数退出,父进程可用exit()函数也可用return退出

      函数功能:创建一个子进程,并阻塞父进程,

      所属头文件:<unistd.h> <sys/types.h>

      返回值:成功时:子进程中:返回0

                      父进程中:返回子进程的ID

              失败时:返回-1

      参数说明:无

    ****************************************************************************/

    4.进程等待

    /*****************************************************************************

      函数名:wait

      函数原型:pid_t wait(int *status)

      函数功能:挂起调用它的子进程,知道其子进程结束

      所属头文件:<sys/types.h> <sys/wait.h>

      返回值:成功时:返回终止的那个子进程的ID

              失败时:返回-1

      参数说明:status:记录子进程退出的原因

    ****************************************************************************/

    5.运行程序

    /*****************************************************************************

      函数名:execl

      函数原型:int execl(const char *path,const char *arg........)

      函数功能:运行可执行的程序

      所属头文件:<unistd.h>

      返回值:成功时:不返回

              失败时:返回-1

      参数说明:path:表示要运行的可执行文件路径

                Arg:可执行文件运行所需的参数,以空指针NULL结束

      调用例程:execl(“/bin/ls”,”ls”,”/home”,NULL);

      特殊说明:如果调用execl函数整个程序的代码段全部变成ls下面的代码了。

                在原来的进程中,用新的代码段替换原有的程序,执行新的程序。

    ****************************************************************************/

    6.运行程序

    /*****************************************************************************

      函数名:system

      函数原型:int system(const char *command)

      函数功能:运行可执行的程序

      所属头文件:<unistd.h>

      返回值:成功时:返回一个状态值

              失败时:返回-1

      参数说明:command:被执行的命令,字符串格式

      调用例程:execl(“/bin/ls”,”ls”,”/home”,NULL);

      特殊说明:如果调用execl函数整个程序的代码段全部变成ls下面的代码了。

                在原来的进程中,先执行system中的命令,在执行其后的数据。

                新的代码段不会替换原有的程序。

    ****************************************************************************/

     

    五.进程间的通信

    /*****************************************************************************

    1通信方式:A.无名管道和有名管道(数据传输)

               B.信号(时间通知)

               C.信号量(资源共享)

               D.消息队列

               E.共享内存

               F.套接字

    2.特殊说明:A.无名管道只能用于子进程和父进程间通信。

               B.有名管道可用于任意两个进程之间通信。

               C.管道通信是单向的,有固定的读端和写端

               D.取走数据后,管道为空。

               E.若管道为空,读取时读进程阻塞,直到有数据可读。        

    ****************************************************************************/

    1.无名管道编程

    /*****************************************************************************

      函数名:pipe

      函数原型:int pipe(int fd[2])

      函数功能:创建一个无名管道

      所属头文件:<unistd.h>

      返回值:成功时:返回0

              失败时:返回-1

      参数说明:fd[0]:指向读端

                fd[1]:指向写端

      特殊说明:可以使用write(),read(),close()等函数操作数据

    ****************************************************************************/

    2.有名管道编程

    1,创建有名管道

    /*****************************************************************************

      函数名:mkfifo

      函数原型:int mkfifo(const char *pathname,mode_t mode)

      函数功能:创建一个无名管道

      所属头文件:<sys/types.h>  <sys/stat.h>

      返回值:成功时:返回0

              失败时:返回-1,错误原因存放于errno

      参数说明:pathname:创建有名管道对应的实名文件路径。该文件必须不存在

                   mode:文件的权限

      特殊说明:可以使用write(),read(),close()等函数操作数据。

                读FIFO文件的进程只能以RDONLY权限读取。

                写FIFO文件的进程只能以WRONLY权限写入数据。

                读完FIFO文件后,文件内容为空。

    ****************************************************************************/

    例程分析:

    #include <stdio.h>  <sys/wait.h>  <unistd.h>  <sys/types.h>

    void main()

    {

        int pipefd[2];    pid_t pid1=0;   char buffer[10];  

        pipe(pipefd);

        pid1 = fork();

        if(pid1>0)

        {  

            write(pipefd[1],"zhou",5);

            wait(NULL);   close(pipefd[1]);  exit(0);

         }

        if(pid1==0)

        { 

               read(pipefd[0],buffer,5);

               close(pipefd[0]);  printf("read is data: %s ",buffer);   exit(0);      

         } 

    }

    ---------------------------------------------------------------------------------------------------------------------

    1,删除有名管道

    /*****************************************************************************

      函数名:unlink

      函数原型:int unlink(const char *pathname)

      函数功能:删除有名管道(有名管道的实质是一个特殊文件)

      所属头文件:<unistd.h>

      返回值:成功时:返回0

              失败时:返回-1,错误原因存放于errno

      参数说明:pathname:创建有名管道对应的实名文件路径名。

    ****************************************************************************/

    例程分析:

    /***********************************写进程代码*******************************/

    #include <sys/types.h>   <sys/stat.h>  <unistd.h>  <fcntl.h>

    void main()

    {

        int fd=0;

        mkfifo("/home/fifo",0666);

        fd = open("/home/fifo",O_WRONLY);

        write(fd,"zhouxue",8);  

        close(fd);

    }

    /*****************************读进程代码********************************/

    #include <sys/types.h>   <sys/stat.h>  <unistd.h>  <fcntl.h>

    void main()

    {

       int fd=0;

       char buffer[10];

       fd = open("/home/fifo",O_RDONLY);

       read(fd,buffer,8);

       printf("read data is  %s ",buffer);

       close(fd); 

       unlink("/home/fifo");

    }

    -------------------------------------------------------------------------------------------------------------------

    3信号通信

    说明linux当中所有的信号都定义在/usr/include/asm/signal.h

    常用信号标志:SIGKILL:该信号结束接收该信号的进程

                  SIGSTOP:来自键盘或调试程序的停止信号

                  SIGINT:来自键盘的中断信号

                  SIGHUP:从终端上发出的结束信号

                  SIGHLD:子进程停止或结束时通知父进程的信号

    ------------------------------------------------------------------------------------------------------------------

    1,发送信号

    /*****************************************************************************

      函数名:kill

      函数原型:int kill(pid_t pid,int sig)

      函数功能:向一个进程发送信号

      所属头文件:<signal.h>  <sys/types.h>

      返回值:成功时:返回0

              失败时:返回-1

      参数说明:Sig:用来指明要发送的信号。

                pid:pid>0:指向接收信号进程的PID。

                    Pid=0:将信号发送给目前进程相同进程组的所有进程。

                    Pid=-1:将信号广播发送给系统所有的进程。

                    Pid<0:将信号发送给进程组识别码为pid绝对值的所有进程。

    ****************************************************************************/

    2设置信号处理的方式

    /*****************************************************************************

      函数名:signal

      函数原型:sig_t signal(int signum, sig_t handler)

                Void(*signal(int signum, void(*handler)(int)))(int)

                Typedef  void(*sig_t)(int)

      函数功能:信号处理

      所属头文件:<signal.h>

      返回值:成功时:返回先前的信号处理函数指针

              失败时:返回SIGERR(-1)

      参数说明:signum:设置辛亥处理函数所依赖的信号编号

                Handler:信号处理函数

              如果handler不是函数指针,则必须是下列常数之一

               SIG_IGN:忽略参数signum指定的信号

               SIG_DFL:将参数signum指定的信号重设为预设的信号处理方式

               第三:用户自己编写一个信号处理函数来处理

    ****************************************************************************/

    3,进程等待

    /*****************************************************************************

      函数名:pause

      函数原型:int pause(void)

      函数功能:让进程暂停直到信号出现

      所属头文件:<unistd.h>

      返回值:只返回-1

      参数说明:无

    ****************************************************************************/

    代码分析:

    -------------------------------------------------------------------------------------------------------------------

    /******************************进程处理******************************/

    #include <unistd.h> <sys/types.h> <stdio.h> <signal.h>

    void main(int argc,char *argv[])

    {    

        pid_t pid;

        pid = atoi(argv[1]);

        kill(pid,SIGINT);  

    }

    /******************************发送信号给进程******************************/

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

    void myfunc(int a)

    {

        printf("the signal to dell ");

    }

    void main()

    {

        signal(SIGINT,myfunc);

        pause();  

    }

    ----------------------------------------------------------------------------------------------------------------------

    七.信号量互斥编程

    /*****************************************************************************

    1创建和打开信号量

    /*****************************************************************************

      函数名:semget

      函数原型:int semget(key_ key,int nsems,int semflag)

      函数功能:打开信号量,当Key所指定的信号量不存在的时候,并且Semflag标识中

               包含了IPC-CREAT标志时,去创建一个信号量集合。

      所属头文件:<sys/types.h>  <sys/ipc.h>  <sys/sem.h>

      返回值:成功:返回信号量的IPC标示符,

              失败:返回-1,错误原因保存在errno中

                  EACCESS:没有权限。

                  EEXIST:信号灯已经存在,无法创建。

                  EIDRM:信号灯集已经删除。

                  ENOENT:信号灯集不存在,同时没有使用IPC_CREAT.

                  ENOMEM:没有足够的内存创建信号灯集。

                  ENOSPC:超出限制。

      参数说明:key:要打开的信号量的键值,可用ftok()函数获取。

                Nsems:创建的信号量集合中的个数。

                Semflag:表示操作类型,也可用于信号灯的访问权限。

    ****************************************************************************/

    2获得IPC键值

    /*****************************************************************************

      函数名:ftok

      函数原型:key_t ftok(const char *pathname,int pid_id)

      函数功能:通过文件路径名和子序列,获得system V IPC键值

      所属头文件:<sys/types.h>  <sys/ipc.h>

      返回值:成功:返回信号量的IPC键值,

              失败:返回-1,错误原因保存在errno中

      参数说明:pathname:指定的带路径的文件名

                Pid_id:子序列id,或工程id

    ****************************************************************************/

    3操作信号量

    /*****************************************************************************

      函数名:semop

      函数原型:int semop(int semid, struct sembuf *sops, unsigned nsops)

      函数功能:操作信号量集合里面的信号灯

      所属头文件:<sys/types.h>  <sys/ipc.h> <sys/sem.h>

      返回值:成功:返回共享内存的起始地址。

              失败:返回-1。

      参数说明:semid:要操作信号量集的标示符。

                Sops:指向待操作的的结构体(数组),sembuf 结构体包含了对某个信号灯的

                     操作方法的信息,其成员如下:

                     Unsigned short  sem_num:要操作的信号灯编号, 从0开始。

                      Short         sem_op:为正数时代表释放信号灯。

                                         为负数时代表获取信号灯,获取失败,进程等待。

                      Short         sem_flag:操作信号灯的标识。

               Nsops用来指定要操作的信号量个数

    ****************************************************************************/

    4初始化信号量

    /*****************************************************************************

      函数名:semctl

      函数原型:int semctl(int semid, int semnum, int cmd,union semun arg)

      函数功能:操作信号量集合里面的信号灯

      所属头文件:<sys/types.h>  <sys/ipc.h> <sys/sem.h>

      返回值:成功:返回命令相关的正数

              失败:返回-1。

      参数说明:semid:信号灯的ID。

              semnum:操作信号灯的编号。

                cmd控制命令,常用的命令有:

                    IPC_RMID:将信号灯集从内存从中删除。

                    GETPID:获得信号灯的ID。

                    GATVAL:获得信号灯的ID。

                    SETVAL:设置信号灯的ID。

                Arg:是一个共同体类型的副本,其中各个量的使用情况和cmd设置有关。

    ****************************************************************************/

    参考例程:

    -----------------------------------------------------------------------------------------------------------------

    /*************************A进程创建信号量*******************************/

    #include <unistd.h>  <sys/sem.h>  <sys/types.h>

    #include  <sys/stat.h>  <fcntl.h> <sys/ipc.h>

    void main()

    {

       int fd = 0 ;  int sops_flag,rest = 0;   key_t key; 

       struct sembuf sops;

       /*获取键值*/

       key = ftok("/home/",1);

       /*创建信号量*/

       sops_flag = semget(key,1,IPC_CREAT);

       /*获取信号量*/

       rest = semctl(sops_flag,0,SETVAL,1);

       printf("the init sopo is: %d ",rest);  

       sops.sem_num = 0;

       sops.sem_op = -1;

       semop(sops_flag,&sops,1);

       /*打开文件*/

       fd = open("/home/txt.c",O_RDWR|O_APPEND); 

       write(fd,"math cless",11);

       sleep(5);//等待信号  

       write(fd,"is quxiao",10); 

       /*释放信号量*/

       sops.sem_num = 0;

       sops.sem_op = +1;

       semop(sops_flag,&sops,1);  

       close(fd);

    }

    /*****************************B进程写文件***********************************/

    #include <unistd.h>  <sys/sem.h>  <sys/ipc.h>

    #include <sys/types.h>  <sys/stat.h>  <fcntl.h>

    void main()

    {

       int fd = 0;   key_t key;  int sops_flag;  struct sembuf sops;  int rest = 0;     

       /*获取键值*/

       key = ftok("/home/",1);

       /*创建信号量*/

       sops_flag = semget(key,1,IPC_CREAT);

       rest = semctl(sops_flag,0,GETVAL);

       printf("the valye is %d ",rest);

       /*获取信号量*/

       sops.sem_num = 0;

       sops.sem_op = -1;

       semop(sops_flag,&sops,1);

       fd = open("/home/txt.c",O_RDWR|O_APPEND);

       write(fd,"einglish cless",15);

       sleep(5);  

       write(fd,"is exam",8);

       /*释放信号量*/

       sops.sem_num = 0;

       sops.sem_op = +1;

       semop(sops_flag,&sops,1);     

      

       close(fd);

    }

    ---------------------------------------------------------------------------------------------------------------------

    八.信号量同步编程

    /*****************************************************************************/

    信号同步编程有生产者和消费者:

         1.生产者要做的有两件事:A.创建信号量。

                                     B.初始化信号量为0

                                     C.只释放信号量能不获取信号量。

         2.消费者要做的事:    A.创建信号量。

                                 B.只获取信号量不释放信号量。

    例程分析:

    ----------------------------------------------------------------------------------------------------------------------/********************************生产者代码***********************************/

    #include <unistd.h>

    #include <fcntl.h>

    #include <sys/sem.h>

    #include <sys/stat.h>

    #include <sys/ipc.h>

     

    void main()

    {

       int fd=0,rest=0,sops_flag=0,key=0;

       struct sembuf sops;

      

       key = ftok("/home/",1);

       sops_flag = semget(key,1,IPC_CREAT);

       rest = semctl(sops_flag,0,SETVAL,0) ;

       fd = open("./txt.c",O_RDWR|O_CREAT,0775);

       sleep(10); 

       write(fd,"the data write seccussed",25);

       sops.sem_num = 0;

       sops.sem_op = +1;

       sops.sem_flag = SEC_UNDO;

      

       semop(sops_flag,&sops,1);

      

       close(fd);

    }

    /*******************************消费者代码********************************/

    #include <unistd.h>

    #include <fcntl.h>

    #include <sys/sem.h>

    #include <sys/stat.h>

    #include <sys/ipc.h>

    #include <stdlib.h>

     

    void main()

    {

       int fd=0,rest=0,sops_flag=0,key=0;

       struct sembuf sops;

      

       key = ftok("/home/",1);

       sops_flag = semget(key,1,IPC_CREAT);

       sops.sem_num = 0;

       sops.sem_op = -1;

       sops.sem_flag = SEC_UNDO;

       semop(sops_flag,&sops,1);

      

       system("cp ./txt.c ./txt1.c");

    }

    ---------------------------------------------------------------------------------------------------------------------

    九。共享内存通讯

    /*****************************************************************************/

     1.基本概念。

    共享内存是IPC机制中的一种,顾名思义,它允许两个相关的进程访问同一段内存,这是传递数据一种非常有效的方式。

    共享内存的作用:在多个不相关进程间传递数据的作用。

    2.函数学习

    1》创建和获取共享内存shmget();

      函数原型: int shmget(key_t key, size_t size, int shmflg);

      头文件: #include <sys/ipc.h>
               #include <sys/shm.h>

      函数功能:创建或者获取一段共享内存,返回内存的描述符。

      返回值: 成功:创建或获取共享内存的描述符。

           失败:-1 。

      参数说明:key_t key:提供共享内存的相关IPC键值。

           size:创建共享内存的大小。

           shmflag: IPC_CREAT:创建一个新的共享内存。如果这个标志不使用,shmget()会发检查用户是否有访问权限一致的共享内存。

    2》映射共享内存shmat()  

      函数作用:指定的共享内存映射到进程的地址空间中。

      函数原型:void *shmat(int shmid, const void *shmaddr, int shmflg);

      头文件:#include <sys/types.h>
                #include <sys/shm.h>

      返回值:成功:返回映射到进程地址空间中的地址。

          失败:

      参数说明:

     

     

     

      

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

                                                                                                                           

  • 相关阅读:
    三星t5拆解
    一条 SQL 引发的事故,同事直接被开除!!
    Git 不能提交空目录?我也是醉了!
    Redis 6.0.8 紧急发布,请尽快升级!
    String.format() 图文详解,写得非常好!
    为什么 Redis 要比 Memcached 更火?
    Lambda 表达式入门,这篇够了!
    天啊,为什么我的 Redis 变慢了。。
    写出一手烂代码的 19 条准则!
    Redis 面试一定要知道的 3 个 问题!
  • 原文地址:https://www.cnblogs.com/zxouxuewei/p/4937046.html
Copyright © 2020-2023  润新知