野火Linux第65/66/67讲:system-V消息队列\信号量\共享内存编程经历
一、消息队列
①学习各种不熟悉的函数
1. strncmp()
库文件:string.h
strncmp函数为字符串比较函数,字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。其函数声明为
int strncmp ( const char * str1, const char * str2, size_t n );
功能是把 str1 和 str2 进行比较,最多比较前 n 个字节,若str1与str2的前n个字符相同,则返回0;若s1大于s2,则返回大于0的值;若s1 小于s2,则返回小于0的值。
2. strncpy()
库文件:string.h
char *strncpy(char *dest, const char *src, int n)
用于将指定长度的字符串复制到字符数组中,表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。
2. perror()
库文件:stdio.h
void perror ( const char * str );
3. exit()
头文件:stdlib.h(如果是”VC6.0“的话头文件为:windows.h)
stdlib.h: void exit(int status);//参 数status,程序退出的返回值
功 能: 关闭所有文件,终止正在执行的进程。
②调试错误
后来发现是自己代码中的用于创建函数队列的 msgget()没设置对,函数原型如下:
int msgget(key_t key,int msgflg) msgflg:IPC_CREAT:如果消息队列不存在,则创建
-
key:消息队列的键值
-
msgflg:
-
IPC_CREAT:如果消息队列不存在,则创建
-
mode:访问权限
-
返回值:
成功:该消息队列的ID
msgget(key,IPC_CREAT|0x666)
将0x666改为0666就可以了。(一种猜想是:虽然两个数字相同,但是16进制可能每一个数比8进制多占了一位)
二、信号量
调试过程中发现两个错误,
一个是官方笔记的参数的错误,应该改为SETVAL(没有前面的IPC_, 否则编译的时候会出现未定义错误)
二是关于运算符优先级的问题,以常见的fork()函数为例,以下代码的红色部分存在错误:
1 pid_t pid; 2 // fork a new process 3 if(pid=fork() < 0) //应该改成 if((pid=fork())<0) 4 { 5 printf("fork failed.\n"); 6 exit(-1); 7 }
“<”的优先级要大于“=”的优先级,因此如果父进程执行的话,因为fork()的值大于0 ----》“<"的逻辑判断为假-----》pid 被赋值为0,发生了错误。
三、共享内存
①别忘记包含头文件哦
包含库函数的规律:一般ipc 包括两个通用的头文件,和一个信号量特用的头文件
1 //通用需要的头文件 2 #include <sys/types.h> 3 #include <sys/ipc.h> 4 5 //信号量特有 6 #include <sys/msg.h> 7 8 //信号量特有 9 #include <sys/sem.h> 10 11 //共享内存特有 12 #include <sys/shm.h>
②、信号量映射内存函数shmat()返回类型说明
函数说明如下
int shmat(int shmid,const void *shmaddr,int shmflg) /* - shmid:共享内存ID - shmaddr:映射地址,NULL为自动分配 - shmflg: - SHM_RDONLY:只读方式映射 - 0:可读可写 返回值: 成功:共享内存首地址 失败:-1 */ 由操作系统申请一段内存,性质为可读可写,返回其共享内存的首地址
该函数原型返回值的类型为int,但是其性质为指针。因此在写程序的时候,常常要做强制类型转化,防止警告。
void *shm = NULL;//定义一个共享内存的指针 //将共享内存连接到当前进程的地址空间,地址由Linux操作系统指定(NULL参数) shm =(void *)shmat(shmid, NULL, 0);