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>

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

      失败:

  参数说明:

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                                                                                                                       

原文地址:https://www.cnblogs.com/zxouxuewei/p/4937046.html