您现在的位置是:主页 > news > 品牌建设工作总结/哪些网站可以seo

品牌建设工作总结/哪些网站可以seo

admin2025/6/25 23:56:11news

简介品牌建设工作总结,哪些网站可以seo,教育培训 营销型网站系统,三星网上商城优惠券1,多个进程或线程有可能同时访问的资源(变量、链表、文件等等)称为共享资源, 也叫临界资源(critical resources)。 2,访问这些资源的代码称为临界代码,这些代码区域称为临界区&#…

品牌建设工作总结,哪些网站可以seo,教育培训 营销型网站系统,三星网上商城优惠券1,多个进程或线程有可能同时访问的资源(变量、链表、文件等等)称为共享资源, 也叫临界资源(critical resources)。 2,访问这些资源的代码称为临界代码,这些代码区域称为临界区&#…

1,多个进程或线程有可能同时访问的资源(变量、链表、文件等等)称为共享资源,
也叫临界资源(critical resources)。
2,访问这些资源的代码称为临界代码,这些代码区域称为临界区(critical zone)。
3,程序进入临界区之前必须要对资源进行申请,这个动作被称为 P 操作,P 操作就是申请资源,如果申请成功,资源数将会减少。
4,程序离开临界区之后必须要释放相应的资源,这个动作被称为 V 操作,V 操作就是释放资源,释放资源就是让资源数增加。
注意:有资源你就可以访问信号量元素,没有资源则访问失败

基本API函数
1.获取信号量函数
在这里插入图片描述

创建信号量时,还受到以下系统信息的影响:
1,SEMMNI:系统中信号量的总数最大值。
2,SEMMSL:每个信号量中信号量元素的个数最大值。
3,SEMMNS:系统中所有信号量中的信号量元素的总数最大值。
Linux 中,以上信息在/proc/sys/kernel/sem 中可查看

2.申请和释放资源(P/V)操作
在这里插入图片描述
在这里插入图片描述
注意:
2.1信号量操作结构体的定义如下:
struct sembuf
{
unsigned short sem_num; /* 信号量元素序号(数组下标) /
short sem_op; /
操作参数 /
short sem_flg; /
操作选项 */
};
请注意:信号量元素的序号从 0 开始,实际上就是数组下标。

2.2根据 sem_op 的数值,信号量操作分成 3 种情况:
2.2.1:当 sem_op 大于 0 时:进行 V 操作,即信号量元素的值(semval)将会被加上
sem_op 的值。如果 SEM_UNDO 被设置了,那么该 V 操作将会被系统记录。V 操作永
远不会导致进程阻塞。

2.2.2当 sem_op 等于 0 时:进行等零操作,如果此时 semval 恰好为 0,则 semop( )
立即成功返回,否则如果 IPC_NOWAIT 被设置,则立即出错返回并将 errno 设置为
EAGAIN,否则将使得进程进入睡眠,直到以下情况发生:
semval 变为 0。
信号量被删除。(将导致 semop( )出错退出,错误码为 EIDRM)
收到信号。(将导致 semop( )出错退出,错误码为 EINTR)

2.2.3当 sem_op 小于 0 时:进行 P 操作,即信号量元素的值(semval)将会被减去
sem_op 的绝对值。如果 semval 大于或等于 sem_op 的绝对值,则 semop( )立即成功
返回,semval 的值将减去 sem_op 的绝对值,并且如果 SEM_UNDO 被设置了,那么该
P 操作将会被系统记录。如果 semval 小于 sem_op 的绝对值并且设置了 IPC_NOWAIT,
那么 semop( )将会出错返回且将错误码置为 EAGAIN,否则将使得进程进入睡眠,直到
以下情况发生:
semval 的值变得大于或者等于 sem_op 的绝对值。
信号量被删除。(将导致 semop( )出错退出,错误码为 EIDRM)
收到信号。(将导致 semop( )出错退出,错误码为 EINTR)

3.获取或者设置信号量的相关属性
在这里插入图片描述
注意以下几点:
3.1这是一个变参函数,根据 cmd 的不同,可能需要第四个参数,第四个参数是一个如
下所示的联合体,用户必须自己定义:

union semun
{int val; /* 当 cmd 为 SETVAL 时使用 */struct semid_ds *buf; /* 当 cmd 为 IPC_STAT 或 IPC_SET 时使用 */unsigned short *array; /* 当 cmd 为 GETALL 或 SETALL 时使用 */struct seminfo *__buf; /* 当 cmd 为 IPC_INFO 时使用 */
};

3.2,使用 IPC_STAT 和 IPC_SET 需要用到以下属性信息结构体:

struct semid_ds
{
struct ipc_perm sem_perm; /* 权限相关信息 */
time_t sem_otime; /* 最后一次 semop( )的时间 */
time_t sem_ctime; /* 最后一次状态改变时间 */
unsigned short sem_nsems; /* 信号量元素个数 */
};
权限结构体如下:
struct ipc_perm
{
key_t __key; /* 该信号量的键值 key */
uid_t uid; /* 所有者有效 UID */
gid_t gid; /* 所有者有效 GID */
uid_t cuid; /* 创建者有效 UID */
gid_t cgid; /* 创建者有效 GID */
unsigned short mode; /* 读写权限 */
unsigned short __seq; /* 序列号 */
};

3.3,使用 IPC_INFO 时,需要提供以下结构体:

struct seminfo
{int semmap; /* 当前系统信号量总数 */int semmni; /* 系统信号量个数最大值 */int semmns; /* 系统所有信号量元素总数最大值 */int semmnu; /* 信号量操作撤销结构体个数最大值 */int semmsl; /* 单个信号量中的信号量元素个数最大值 */int semopm; /* 调用 semop( )时操作的信号量元素个数最大值 */int semume; /* 单个进程对信号量执行连续撤销操作次数的最大值 */int semusz; /* 撤销操作的结构体的尺寸 */int semvmx; /* 信号量元素的值的最大值 */int semaem; /* 撤销操作记录个数最大值 */
};

3.4,使用 SEM_INFO 时,跟 IPC_INFO 一样都是得到一个 seminfo 结构体,但其中几个
成员的含义发生了变化:
semusz 此时代表系统当前存在的信号量的个数
semaem 此时代表系统当前存在的信号量中信号量元素的总数

4.例子
使用信号来实现两个进程间同步互斥访问共享内存
进程1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <strings.h>#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>#include <wiringPi.h> #define SHMSIZE 128		//共享内存的大小(byte)
#define PASHKEY "." 	// 用以产生键值 key
#define SHM_PROJKEY 1	// 用以产生键值 key
#define SEM_PROJKEY 2	// 用以产生键值 key#define DATA	0		//定义DATA为信号量第0个元素
#define SPACE 	1		//定义SPACE为信号量第1个元素int semid;
int shmid;
char *shmaddr = NULL;union semun // 自定义的信号量操作联合体
{int val;struct semid_ds *buf;unsigned short *array;struct seminfo *__buf;
};static void seminit(int semid, int semnum, int value)	//初始化信号量的第几个元素的初始值
{union semun a;a.val = value;semctl(semid, semnum, SETVAL, a);
}static void sem_p(int semid, int semnum)	//申请信号量第几个元素资源
{struct sembuf op[1];	//该结构体告诉内核,对信号量元素是申请还是释放op[0].sem_num = semnum;	//信号量的第几个元素op[0].sem_op = -1;		//对信号量元素进行资源加减操作op[0].sem_flg = 0;//信号量元素进行申请(p)操作semop(semid, op, 1);	//op:信号量要操作的结构体数组,1:信号量结构体数组元素有几个
}static void sem_v(int semid, int semnum)	//释放信号量第几个元素资源
{struct sembuf op[1];op[0].sem_num = semnum;op[0].sem_op = 1;op[0].sem_flg = 0;//信号量元素进行释放(v)操作semop(semid, op, 1);//op:信号量要操作的结构体数组,1:信号量结构体数组元素有几个
}char *shm_Creat128Byte(void)
{key_t key1 = ftok(PASHKEY, SHM_PROJKEY); // 获取 SHM 对应的键	int shmid = shmget(key1, SHMSIZE, IPC_CREAT|0644);// 获取 SHM 的 ID,并将之映射到本进程虚拟内存空间中return ((char *)shmat(shmid, NULL, 0));		//NULL让系统自动分配映射地址,0:默认映射内存可读可写	
}void routine1(int signum) 
{printf("SEM2 exit handler.\n");semctl(semid, DATA, IPC_RMID);	//删除信号量元素DATAsemctl(semid, SPACE, IPC_RMID);	//删除信号量元素SPACEshmdt(shmaddr);					//解除共享内存映射shmctl(shmid, IPC_RMID, NULL);	//删除共享内存exit(0);
}int main(int argc, void *srgv[])
{int	i = 0;int semval = 0; //记录信号量元素值signal(SIGINT, routine1);	//捕获信号SIGINTshmaddr = shm_Creat128Byte();	//共享内存的获取和映射key_t shmkey = ftok(PASHKEY, SEM_PROJKEY); // 获取 SEM 对应的键semid = semget(shmkey, 2, IPC_CREAT|IPC_EXCL|0644);// 获取 SEM 的 ID,并申请含2个元素的信号量if(semid == -1 && errno == EEXIST)	//如果信号量已经存在,不需要初始化信号量元素的初始值{semid = semget(shmkey, 2, 0644); // 直接获取 SEM 的 ID}else{seminit(semid, DATA, 0); 	// 将信号量第 0 个元素初始值为 0,代表数据seminit(semid, SPACE, 1); 	// 将信号量第 1 个元素初始值为 1,代表空间}while(1){semval = semctl(semid, SPACE, GETVAL);//获取信号量元素值if(semval > 0)//有资源就申请资源{sem_p(semid, SPACE); // 向第 1 个信号量元素申请内存空间资源sprintf(shmaddr, "sem1 to sem2 %d\n", i++);sem_v(semid, DATA); // 增加代表数据资源的第 0 个信号量元素的值		}printf("sem1 running\n");delay(1000); //ms}	
}

例子2

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <strings.h>#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>#include <wiringPi.h> #define SHMSIZE 128		//共享内存的大小(byte)
#define PASHKEY "." 	// 用以产生键值 key
#define SHM_PROJKEY 1	// 用以产生键值 key
#define SEM_PROJKEY 2	// 用以产生键值 key#define DATA	0		//定义DATA为信号量第0个元素
#define SPACE 	1		//定义SPACE为信号量第1个元素int semid;
int shmid;
char *shmaddr = NULL;
//semun:当semctl函数的第四个参数需要填写时,就要自己定义
union semun // 自定义的信号量操作联合体
{int val;struct semid_ds *buf;unsigned short *array;struct seminfo *__buf;
};static void seminit(int semid, int semnum, int value)	//初始化信号量的第几个元素的初始值
{union semun a;a.val = value;semctl(semid, semnum, SETVAL, a);
}static void sem_p(int semid, int semnum)	//申请信号量第几个元素资源
{struct sembuf op[1];	//该结构体告诉内核,对信号量元素是申请还是释放op[0].sem_num = semnum;	//信号量的第几个元素op[0].sem_op = -1;		//对信号量元素进行资源加减操作op[0].sem_flg = 0;//信号量元素进行申请(p)操作semop(semid, op, 1);	//op:信号量要操作的结构体数组,1:信号量结构体数组元素有几个
}static void sem_v(int semid, int semnum)	//释放信号量第几个元素资源
{struct sembuf op[1];op[0].sem_num = semnum;op[0].sem_op = 1;op[0].sem_flg = 0;//信号量元素进行释放(v)操作semop(semid, op, 1);//op:信号量要操作的结构体数组,1:信号量结构体数组元素有几个
}char *shm_Creat128Byte(void)
{key_t key1 = ftok(PASHKEY, SHM_PROJKEY); // 获取 SHM 对应的键	shmid = shmget(key1, SHMSIZE, IPC_CREAT|0644);// 获取 SHM 的 ID,并将之映射到本进程虚拟内存空间中return ((char *)shmat(shmid, NULL, 0));		//NULL让系统自动分配映射地址,0:默认映射内存可读可写	
}void routine1(int signum) 
{printf("SEM2 exit handler.\n");semctl(semid, DATA, IPC_RMID);	//删除信号量元素DATAsemctl(semid, SPACE, IPC_RMID);	//删除信号量元素SPACEshmdt(shmaddr);					//解除共享内存映射shmctl(shmid, IPC_RMID, NULL);	//删除共享内存exit(0);
}int main(int argc, void *srgv[])
{int semval = 0; //记录信号量元素值signal(SIGINT, routine1);	//捕获信号SIGINTshmaddr = shm_Creat128Byte();	//共享内存的获取和映射key_t shmkey = ftok(PASHKEY, SEM_PROJKEY); // 获取 SEM 对应的键semid = semget(shmkey, 2, IPC_CREAT|IPC_EXCL|0644);// 获取 SEM 的 ID,并申请含2个元素的信号量if(semid == -1 && errno == EEXIST)	//如果信号量已经存在,不需要初始化信号量元素的初始值{semid = semget(shmkey, 2, 0644); // 直接获取 SEM 的 ID}else{seminit(semid, DATA, 0); // 将信号量第 0 个元素初始值为 0,代表数据标志seminit(semid, SPACE, 1);// 将信号量第 1 个元素初始值为 1,代表空间标志}while(1){semval = semctl(semid, DATA, GETVAL);//获取信号量元素值if(semval > 0)//有资源就申请资源{sem_p(semid, DATA); // 向第 0 个信号量元素申请数据资源printf("from sem: %s", shmaddr);sem_v(semid, SPACE); // 增加代表空间资源的第 1 个信号量元素的值}printf("sem2 running\n");delay(500); //ms	}
}