进程间通信:进程之间的沟通交流
进程间为什么要沟通交流?
在实际工作中往往会出现在一个系统中好几个进程协同工作,那么这些进程就需要沟通交流,完成协作,而由于进程的独立性, 进程间的沟通变得困难,复杂。因此就产生了各种进程间通信方式,来解决如何进行进程间通信的问题。
进程间通信的目的:
数据传输:一个进程需要将它的数据发送给另一个进程;
资源共享:多个进程间共享同样的资源;
通知事件:一个进程需要向另一个或一组进程发消息,通知它们发生了某种事件(如进程终止时要通知父进程)。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
进程间通信方式:
1.管道
管道:传输资源。本质上是内核的一块缓冲区。(特性:半双工,单向通信)。 Linux一切皆文件,操作系统为管道提供操作的方法:文件操作
⽤用fork来共享管道原理 :
这里写图片描述
站在⽂文件描述符⾓角度-深度理解管道 :
这里写图片描述

管道分为:匿名管道/命名管道
匿名管道
没有名字的管道(仅用于具有亲缘关系(父子,兄弟等)的进程间通信)。
创建匿名管道:pipe

#include <unistd.h>
int pipe(int pipefd[2]);
pipefd:用于接受匿名管道创建成功后返回的两个描述符,两个描述符用于对管道进行操作(文件io操作)
pipefd[0]:用于从管道读取数据;
pipefd[1]:用于向管道写入数据
返回值: 返回:0    失败: -1

匿名管道原理:以父子进程为例:创建一个子进程,子进程复制了父进程的描述符表,因此子进程也有描述符表,并且他们指向的是同一个管道,由于父子进程都能访问这个管道,就可以通信。
因为管道是半双工单向通信,因此在通信前要确定数据流向:即关闭父子进程各自一端不用的读写。如果一方是读数据就关闭写的描述符。

 //这是一个匿名管道实现:功能:从父进程写入数据,子进程读取数据#include<stdio.h>#include<unistd.h>#include<string.h>#include<errno.h>int main()
{int fd[2];//管道需要创建在创建子进程前,这样才能复制if(pipe(fd)<0){perror("pipe errno");return -1;}int pid=-1;pid=fork();//创建子进程,对于父进程会返回子进程id,子进程会返回0,创建失败会返回0if(pid<0){perror("fork errno");return -1;}else if(pid==0){//子进程 读取数据-> fd[0]close(fd[1]);//fd[1]是向管道写入数据,子进程不用写入数据,需要关闭管道写入端char buff[1024]={0};read(fd[0],buff,1024);//如果管道没数据会等待,然后读取数据,默认阻塞等待直至有数据printf("buff:%s\n",buff);close(fd[0]);}else {//父进程 :写入数据->fd[1]close(fd[0]); //fd[0]是读取数据,父进程不用读取数据,需要关闭管道读取端,由于父子进程相互独立,关闭一方描述符对另一方无影响   write(fd[1],"happy day",10);close(fd[1]);}return 0;}

实现ps -f | grep ssh

   //实现 ps -ef | grep ssh// 父进程将ps -ef 写入管道,子进程读取管道里的数据#include<stdio.h>#include<unistd.h>#include<error.h>#include<string.h>int main(){int pipefd[2];if(pipe(pipefd)<0){perror("pipe error");return -1;}int pid=fork();if(pid<0){perror("fork error");return -1;}else if(pid==0){//子进程 grep ssh//grep这个进程原本从标准输入(0)读取数据,但是现在需要从管道读取数据,所以需要把标准输入重新定向到管道读取端close(pipefd[1]); //关闭子进程写入端dup2(pipefd[0],0);//标准输入0定向为管道读取端execlp("grep","grep","ssh",NULL);//替换close(pipefd[0]);}else{//子进程 ps -f// ps 这个进程原本把数据写入到标准输出,即打印到显示器上,但是现在需要把数据写入到管道,所以需要把标准输出重新定向为到管道写入端close(pipefd[0]); //关闭父进程读取端dup2(pipefd[1],1); //标准输出1定向为管道写入端execlp("ps","ps","-ef",NULL); //替换close(pipefd[1]);}return 0;
}

匿名管道特性:
1.只能用于具有亲缘关系的进程间通信;
2.管道是半双工单向通信;(两个文件描述符,用一个,另一个不用,不用的文件描述符就要close)
3.管道的生命周期随进程(打开管道的所有进程退出,管道释放);
4.管道是面向字节流传输数据。(面向字节流:数据无规则,没有明显边界,收发数据比较灵活:对于用户态,可以一次性发送也可以分次发送,当然接受数据也如此;而面向数据报:数据有明显边界,数据只能整条接受 )
5.内核会对管道操作进行同步与互斥;
临界资源: 大家都能访问到的共享资源
临界区: 对临界资源进行操作的代码
同步: 临界资源访问的可控时序性(一个操作完另一个才可以操作)
互斥: 对临界资源同一时间的唯一访问性(保护临界资源安全)
匿名管道读写规则:
1.管道无数据读取(read): 如果描述符是默认的阻塞特性,读取将会阻塞挂起等待,直到管道有数据;
2.管道被写满(write):如果描述符是默认的阻塞特性,写入操作会阻塞挂起等到,直到有数据被取走;如果描述符被设置为非阻塞特性,写入操作不具备条件,直接报错返回-1,错误码:EAGAIN。
3.如果所有管道
写入端对应的文件描述符被关闭
,则读取完管道中数据,然后read返回0;
4.如果所有管道读取端对应的文件描述符被关闭,则write操作会触发异常(因为没有人读数据),操作系统会给进程发送SIGPIPE,进程收到这个进程会退出;
5.当要写入的数据量不大于PIPE_BUF(512字节)时,linux将保证写入的原子性(操作不会被打断,一步完成);
6.当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。
命名管道
命名管道:文件系统可见,是一个特殊类型(管道类型)文件,命名管道可以应用于同一主机上任意进程间通信。
命名管道创建:

1.命令创建:mkfifo  管道名
2.代码创建:#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);pathname:  管道文件的路径名;mode:         管道文件的权限;成功返回 : 0,失败返回 :-1

命名管道打开特性:
1. 如果用只读打开命名管道,open函数将阻塞等待直至有其他进程以写的方式打开这个命名管道,如果没有进程以写的方式发开这个命名管道,程序将停在此处
2.如果用只写打开命名管道,open函数将阻塞等到直至有其他进程以读的方式打开这个命名管道,如果没有进程以读的方式发开这个命名管道,程序将停在此处;
3.如果用读写打开命名管道,则不会阻塞(但是管道是单向)

// 命名管道代码操:作,从命名管道中读取数据打印#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
int main()
{//用mkfifo创建管道umask(0);  //将掩码设置为0if(mkfifo("./test.fifo",0664)<0){if(errno==EEXIST);//由于mkdir只能创建不存在命名管道,如果存在会报错,在这里如果存在继续走下面代码else{perror("mkfifo error");return -1;}}//用open打开管道int fd=open("./test.fifo",O_RDONLY);//用只读打开命名管道,open函数将阻塞等到直至有其他进程以写的方式打开这个命名管道,如果没有进程以写的方式打开这个命名管道,程序将停在此处if(fd<0){perror("open error");return -1;}printf("open fifo  sucess and start read\n");//从管道中读取数据while(1){char buff[1024]={0};int ret= read(fd,buff,1024); //管道是缓冲区,所以读取数据从缓冲区开始读;并且是单工通信(读或写一种)if(ret>0)printf("[%s]\n",buff);// 管道特性:如果所有写端(echo 写完退出test.fifo,就是关闭了写端)关闭,那么读取时返回0else if(ret==0){printf("all write closed\n");sleep(3);}}//关闭管道close(fd);return 0;
}

这里写图片描述
这里写图片描述
例:用命名管道实现server&client通信(一个写数据,一个将数据输出)

//fifo_a.c(以写的方式打开)
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
int main()
{//用mkfifo创建管道umask(0);  //将掩码设置为0if(mkfifo("./test.fifo",0664)<0){if(errno==EEXIST);//由于mkdir只能创建不存在命名管道,如果存在会报错,在这里如果存在继续走下面代码else{perror("mkfifo error");return -1;}}//用open打开管道int fd=open("./test.fifo",O_WRONLY);//用只写打开命名管道,open函数将阻塞等到直至有其他进程以读的方式打开这个命名管道,如果没有进程以读的方式发开这个命名管
道,程序将停在此处if(fd<0){perror("open error");return -1;}//从管道中读取数据while(1){char buff[1024]={0};scanf("%s",buff);write(fd,buff,strlen(buff));sleep(1);}//关闭管道close(fd);return 0;
}

这里写图片描述
命名管道和匿名管道区别和联系:
1.区别:匿名管道用int pipe(int pipefd[2]); 创建并打开匿名管道返回描述符
命名管道用mkfifo或者 int mkfifo(const char *pathname, mode_t mode);创建,并没有打开,如果打开需要open;
匿名管道是具有亲缘关系进程间通信的媒介,而命名管道作为同一主机任意进程间通信的媒介;
匿名管道不可见文件系统,命名管道可见于文件系统,是一个特殊类型(管道类型)文件。
2.联系:匿名管道和命名管道都是内核的一块缓冲区,并且都是单向通信;另外当命名管道打开(open)后,所有特性和匿名管道一样(上文匿名管道读写规则与管道特性):两者自带同步(临界资源访问的时序性)与互斥(临界资源同一时间的唯一访问性),管道生命周期随进程退出而结束。
消息队列(System V IPC)
消息队列实际上是操作系统在内核为我们创建的一个队列,通过这个队列的标识符key,每一个进程都可以打开这个队列,每个进程都可以通过这个队列向这个队列中插入一个结点或者获取一个结点来完成不同进程间的通信。
如何传输数据:
用户组织一个带有类型的数据块,添加到队列中,其他的进程从队列中获取数据块,即消息队列发送的是一个带有类型的数据块;消息队列是一个全双工通信,可读可写(可以发送数据,也可以接受数据)
消息队列生命周期随内核,如果没有释放消息队列或者没有关闭操作系统,消息队列会一直存在。
创建消息队列:

msgget:
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
key: 内核中消息队列的标识
msgflg:IPC_CREAT :不存在消息队列则创建,存在则打开IPC_EXCL   :与 IPC_CREAT 同用时,存在则报错mode  :权限
返回值:代码操作的句柄 ,失败: -1

接收数据:

msgrcv:是从一个消息队列接收数据
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtype, int msgflg);
msgrcv  默认阻塞的获取数据(即没有数据,会一直等待)
msqid: msgget返回的操作句柄;
msgp  :用于接受数据
msgsz:   指定接受数据的大小(不包括mtype)
msgtype: 指定接受的数据类型msgtype=0 取队列中字一个节点,不分类型;msgtype>0 取指定类型数据块的第一个节点;msgtype<0 取队列中第一条类型数据块小于等于msgtype绝对值的节点,并且是满足条件的消息类型最小的节点。
msgflg: 标志选项,0(默认);MSG_NOERROR ,当数据长度超过指定长度,则截断数据

发送数据:

msgsnd: 把一条消息添加到消息队列中
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

通过类型判断接受何种数据
如果是不正常退出(Ctrl+C),消息队列存在,如果发送一条消息,用ipcs查看消息队列:

这里写图片描述
用ipcrm -q msqid 删除msgqid的消息队列,然后用ipcs -q 查看没有消息队列。
消息队列控制函数:

msgctl:#include <sys/ipc.h>#include <sys/msg.h>int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgqid:由msgget函数返回的消息队列标识码;
cmd是将要采取的动作(有三个可取值):IPC_STAT:把msqid_ds结构中的数据设置为消息队列的当前关联值;IPC_SET: 在进程有足够权限的前提下,把消息队列的当前关联值设置为msqid_ds数据结构中给出的值;IPC_RMID :删除消息队列
//  这是一个以System V 消息队列实现的聊天程序客户端
//  1.创建消息队列
//  2.从消息队列获取一个数据,并且打印出来
//  3.从标准输入获取一个数据,组织成消息队列节点发送
//  4.不玩了,删除消息队列
//  消息队列接口: msgget  msgrcv msgsnd msgctl
//
//
//        #include <sys/ipc.h>
//        key_t ftok(const char *pathname, int proj_id);
//        ftok通过文件的inode结点号和一个proj_id计算得出一个key值
//        缺点:如果一个进程将文件删除或替换,那么另一个进程打开的不是同一个文件,所以在本程序中直接给出key值
msgqueue_s.c 先接收数据再发送数据
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<errno.h>
#include<string.h>#define IPC_KEY 0X12345678
#define TYPE_C 1  //msgtype
#define TYPE_S 2struct msgbuf {long mtype;       /* message type, must be > 0 */char mtext[1024];    /* message data */};int main()
{int msqid=-1;//int msgget(key_t key, int msgflg);//key :消息队列标识符,msgflg:IPC_CREAT :不存在消息队列则创建,存在则打开//创建消息队列msqid=msgget(IPC_KEY,IPC_CREAT |0664);if(msqid<0){   perror("msgget error");return -1;}while(1){//接受数据//ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtype,int msgflg);struct msgbuf buff;msgrcv(msqid,&buff,1024,TYPE_C,0);//msqid :消息队列操作句柄;//&buff 接受数据的结构体,需要自己定义//1024 接受数据的最大数据长度,不包含mtype//0 如果数据长度超过指定长度不截断,如果参数是MSG_NOERROR 将会截断数据printf("[%s]\n",buff.mtext); //将接受的数据打印//发送数据memset(&buff,0,sizeof(struct msgbuf));//先将数据初始化为0buff.mtype=TYPE_S;scanf("%s",buff.mtext);//  int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);msgsnd(msqid,&buff,1024,0);//并不是全部发送1024字节,会发生strlen(buff)}//一般用ctrl+c使进程停止,没有运行到这里,也就意味着没有删除消息队列//删除消息队列:IPC_RMID  第三个参数是删除后获取消息队列属性信息,如果不想获取可以置NULL//int msgctl(int msqid, int cmd, struct msqid_ds *buf);msgctl(msqid,IPC_RMID,NULL);return 0;
}
msgqueuq_c.c 先发送数据,再接收数据
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<errno.h>
#include<string.h>#define IPC_KEY 0X12345678
#define TYPE_C 1
#define TYPE_S 2struct msgbuf {long mtype;       /* message type, must be > 0 */char mtext[1024];    /* message data */};  int main()
{int msqid=-1;//int msgget(key_t key, int msgflg);//key :消息队列标识符,msgflg:IPC_CREAT :不存在消息队列则创建,存在则打开//创建消息队列msqid=msgget(IPC_KEY,IPC_CREAT |0664);if(msqid<0){   perror("msgget error");return -1;}while(1){//发送数据struct msgbuf buff;memset(&buff,0,sizeof(struct msgbuf));//先将数据初始化为0buff.mtype=TYPE_C;scanf("%s",buff.mtext);//  int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);msgsnd(msqid,&buff,1024,0);//接受数据//ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);msgrcv(msqid,&buff,1024,TYPE_S,0);//msqid :消息队列操作句柄;//&buff 接受数据的结构体,需要自己定义//1024 接受数据的最大数据长度,不包含mytype//0 如果数据长度超过指定长度不截断,如果参数是MSG_NOERROR 将会截断数据printf("[%s]\n",buff.mtext); //将接受的数据打印}//删除消息队列:IPC_RMID  第三个参数是删除后获取消息队列属性信息,如果不想获取可以置NULL//int msgctl(int msqid, int cmd, struct msqid_ds *buf);msgctl(msqid,IPC_RMID,NULL);return 0;
}

这里写图片描述
操作系统中ipc相关命令:
ipcs : 查看ipc信息
ipcs -q :查看消息队列
ipcs -m :查看共享内存
ipcs -s :查看信号量
ipcrm : 删除ipc
ipcrm -q msqid 删除指定的消息队列
ipcrm -m msqid 删除指定的共享内存
ipcrm -s msqid 删除指定的信号量
共享内存(进程间最快通信)
一般数据操作过程把数据从用户态拷贝到内核态,用的时候,再将内核态拷贝到用户态,但共享内存不需要这两步,对虚拟地址空间的操作也就是操作了物理内存,那么另一个虚拟地址空间也可以有这个数据,即不需要拷贝。
因为共享内存直接申请一块物理内存通过页表映射到虚拟地址空间中,操作虚拟地址空间,其实是操作同一块物理内存区域,因此进行数据传输时相较于其他通信方 式,少了两步用户态与内核态数据拷贝的过程,因此共享内存是最快的进程间通信方式。
这里写图片描述
共享内存使用步骤:
1.创建共享内存
2.将共享内存映射到虚拟地址空间
3.内存的数据操作(数据拷贝)
4.解除映射,删除共享内存(如果有进程依然与共享内存保持映射连接关系,那么共享内存将不会被立即删 除,而是等最后一个映射断开后删除,在这期间,将拒绝其他进程映射)
1.创建:

shmget:#include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);key  :操作系统上ipc标识,这个共享内存段名字
size :  要创建共享内存大小
shmflg: IPC_CREAT | IPC _EXCL |0664返回值:成功: 操作句柄   失败: -1

2.映射到虚拟地址空间

#include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg);
shmid: 操作句柄
shmaddr: 映射起始地址,NULL(随机选择操作系统分配) 
shmflg:  SHM_RDONLY 只读,其他参数(0)为读写
返回值:映射的虚拟地址空间首地址
失败返回-1

3.解除映射:

int shmdt(const void shmddr);
shmddr; 由shmat返回的指针,共享内存的映射首地址
返回值: 成功: 0,失败-1

删除:

#include <sys/ipc.h>
#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid: 操作句柄
cmd: IPC_RMID  删除(共享内存映射链接数为0,才会删除)
buf:  用于接受共享内存描述信息,不关系可以置空
删除一个共享内存时,如果这个共享内存依然与其他进程有映射连接,这个时候共享内存不会被直接删除,而是等到所有进程都与这个共享内存解除映射关系才会删除
//这是一个基于共享内存的进程间聊天程序
//  共享内存操作步骤:
//  1.创建共享内存
//  2.将共享内存映射到虚拟地址空间
//  3.内存的数据操作(数据拷贝)
//  4.解除映射,删除共享内存(如果有进程依然与共享内存保持映射连接关系,那么共享内存将不会被立即删除,>而是等最后一个映射断开后删除,在这期间,将拒绝其他进程映射)
//写数据
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<errno.h>
#include<string.h>#define SHM_KEY 0x12345678
int main()
{int shmid=-1;//创建共享内存//int shmget(key_t key, size_t size, int shmflg);shmid=shmget(SHM_KEY,32,IPC_CREAT | 0664);if(shmid<0)
if(shmid<0){perror("shmget errnor");return -1;}//建立映射关系// void *shmat(int shmid, const void *shmaddr, int shmflg);void *shm_start=shmat(shmid,NULL,0); // 0是读写  返回的是虚拟地址空间首地址 ,失败返回-1if(shm_start<0){perror("shmat error");return -1;}//向内存写内容while(1){printf("please input:");fflush(stdout);memset(shm_start,0,32);scanf("%s",(char *)shm_start);sleep(3);}//解除映射//int shmdt(const void shmddr);//由shmat返回的指针shmdt(shm_start);//删除(共享内存映射连接数为0)//int shmctl(int shmid, int cmd, struct shmid_ds *buf);shmctl(shmid,IPC_RMID,NULL);return 0;
}
//读数据
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<errno.h>
#include<string.h>#define SHM_KEY 0x12345678
int main()
{int shmid=-1;//创建共享内存//int shmget(key_t key, size_t size, int shmflg);shmid=shmget(SHM_KEY,32,IPC_CREAT | 0664);if(shmid<0){perror("shmget errnor");return -1;}//建立映射关系// void *shmat(int shmid, const void *shmaddr, int shmflg);void *shm_start=shmat(shmid,NULL,0); // 0是读写  返回的是虚拟地址空间首地址 ,失败返回-1if(shm_start<0){perror("shmat error");return -1;}//向内存写内容while(1){printf("%s\n",(char *)shm_start);sleep(3);}//解除映射//int shmdt(const void shmddr);//由shmat返回的指针shmdt(shm_start);//删除(共享内存映射连接数为0)//int shmctl(int shmid, int cmd, struct shmid_ds *buf);shmctl(shmid,IPC_RMID,NULL);return 0;
}
注意:scanf和printf循环语句里sleep()时最好保持一样

这里写图片描述
信号量:(本质:具有一个等待队列的计数器(现在是否有资源可以使用))
进程间通信方式之一,用于实现进程间的同步与互斥(进程与线程安全概念)
同步:保证对临界资源访问的时序可控性(保证有序);
互斥:对临界资源同一时间的唯一访问性(保证安全)。
多个进程同时,操作一个临界资源的时候就需要通过同步与互斥机制开实现对临界资源的安全访问;
当信号量没有资源可用(计数器为0)时,这时需要阻塞等待 ;
同步:只有信号量资源计数从0变为1的时候,会通知别人打断阻塞等待,去操作临界资源,也就是释放了资源(计数器+1)之后才能获取资源(计数器-1),然后进行操作;
互斥:信号量如果想要实现互斥,那么它的计数器只能是0/1(一元信号量),我获取的计数器的资源,那么别人就无法获取。
P操作:获取信号量资源及计数器-1操作,如果计数器为0,需要等待别人释放资源。
V操作:释放信号量资源及计数器+1操作;
进程在操作临界资源之前要先获取信号量,判断是否可以对临界资源进行操作,如果信号量没有资源(计数器为0),则需要等待,当别人释放信号量资源后信号量计数变为1,则会唤醒等待的进程去重新获取信号量资源。
信号量计数器大于0,代表信号量有资源,可以操作;
信号量计数器等于0,代表信号量没有资源,需要等待。

信号量作为进程间通信方式,意味着大家都能访问到信号量,信号量实际也是一个临界资源,当然信号量的这个临界资源的操作是不会出问题的,因为信号量的操作是一个原子操作。
信号量操作步骤:
创建信号量:

semget   
#include <sys/ipc.h>
#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);
key:  信号集名字
nsems: 指定一次要创建多少个信号量
semflg: IPC_CREAT |0644 和mode使用方法一样
返回值:成功:信号集标识码    失败 :-1
system V标准的信号量可以一次创建一个集合(可以包含多个信号量的同时创建)

设置信号量初值:

semctl:#include <sys/ipc.h>#include <sys/sem.h>int semctl(int semid, int semnum, int cmd, ...);
semid : 由semget返回的信号集标识码
semnum: 指定要操作第几个信号量(从0开始)
cmd :  具体的操作SETVAL :设置单个信号量的初值SETALL:  设置所有的信号量的初值(semnum将会被忽略)IPC_RMID :删除信号集
...:第四个参数,是一个不定参数,比如要获取信号量的信息,那么第四个参数就是结构体;比如要设置信号量的值,那么第四个参数就是值的联合体
设置初值:(联合体)
union semun {int              val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */};
在对临界资源操作之前要先获取信号量 (计数器-1)
对临界资源操作完毕后要释放信号量(计数器+1)

访问信号量

#include <sys/ipc.h>
#include <sys/sem.h>int semop(int semid, struct sembuf *sops, unsigned nsops);
semid: semget返回值;
spos: 是一个指向结构体的指针;结构体如下:
struct sembuf{
unsigned short sem_num;  /* semaphore number */short          sem_op;   /* semaphore operation */short          sem_flg;  /* operation flags */
}
sem_num:信号量编号
sem_op:信号量一次pv操作时加减的数值,-1 即p操作,获取资源,+1 即v操作,释放资源
sem_flag:IPC_NOWAIT:退出,没有释放资源;IPC_UNDO :退出,会释放资源

下面两个代码分别利用信号的互斥和同步实现代码

//这是一个基于信号量的互斥实现代:码
// 让一个进程打印A睡1000ms然后再打印一个A
// 另一个进程打印B睡1000ms然后再打印一个B
// 查看结果是否连续
// 如何让结果是我们预期的AA  BB这种形式,关键在于两个进程的打印操作不能被打断,
// 这时需要一个一元信号量来完成互斥操作#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/sem.h>#define SEM_KEY 0x12345678
union semun {int              val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};
//struct sembuf{
//      unsigned short sem_num;  /* semaphore number */
//      short          sem_op;   /* semaphore operation */
//      short          sem_flg;  /* operation flags */
//      }  //semop第二个参数
void sem_p(int semid)//获取资源
{struct sembuf buf;buf.sem_num=0;buf.sem_op=-1;buf.sem_flg=SEM_UNDO;//       int semop(int semid, struct sembuf *sops, unsigned nsops); semop(semid,&buf,1);
}
void sem_v(int semid)//释放资源
{struct sembuf buf;buf.sem_num=0;buf.sem_op=+1;buf.sem_flg=SEM_UNDO;//       int semop(int semid, struct sembuf *sops, unsigned nsops); semop(semid,&buf,1);
}int main()
{//创建信号量int semid=-1;// int semget(key_t key, int nsems, int semflg);semid=semget(SEM_KEY,1,IPC_CREAT | 0664);if(semid<0){perror("semget error");return -1;}//设置信号量初值://只能设置一次,不能重复设置,并且在创建子进程之前union semun val;val.val=1; //将信号量计数器设置为1//       int semctl(int semid, int semnum, int cmd, ...);semctl(semid,0,SETVAL,val);//由于要设置信号量初值,semctl第四个参数为联合体,信号量从0开始      int pid=-1;pid=fork();if(pid<0){perror("fork error");return -1;}else if(pid==0)else if(pid==0){//子进程 打印Awhile(1){//获取信号量资源sem_p(semid);//对于一元信号量,当这个进程获取信号量之后,那么另一个进程将获取不到信号量,会等待即在释放信号量之前,此进程的临界操作不会被打断printf("A");fflush(stdout);usleep(1000);//如果没有信号量,子进程睡了1000us,父进程可能会打印Bprintf("A ");fflush(stdout);//释放信号量资源sem_v(semid);}}else{//父进程  打印Bwhile(1){//获取信号量资源sem_p(semid);printf("B");fflush(stdout);usleep(1000);printf("B ");fflush(stdout);//释放信号量资源sem_v(semid);}}return 0;
}

这里写图片描述

//这是一个基于信号量同步的实现代码
//只有生产了面,才有资源吃面#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/sem.h>#define SEM_KEY 0x12345678
union semun {int              val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};
//struct sembuf{
//      unsigned short sem_num;  /* semaphore number */
//      short          sem_op;   /* semaphore operation */
//      short          sem_flg;  /* operation flags */
//      }  //semop第二个参数
void sem_p(int semid)//获取资源
{struct sembuf buf;buf.sem_num=0;buf.sem_op=-1;buf.sem_flg=SEM_UNDO;//       int semop(int semid, struct sembuf *sops, unsigned nsops);semop(semid,&buf,1);
}
void sem_v(int semid)//释放资源
{struct sembuf buf;buf.sem_num=0;buf.sem_op=+1;buf.sem_flg=SEM_UNDO;//       int semop(int semid, struct sembuf *sops, unsigned nsops);semop(semid,&buf,1);
}int main()
{//创建信号量int semid=-1;semid=semget(SEM_KEY,1,IPC_CREAT | 0664);if(semid<0){perror("semget error");return -1;}//设置信号量初值:union semun val;val.val=0; //将信号量计数器设置为0,即没有资源可以使用//       int semctl(int semid, int semnum, int cmd, ...);semctl(semid,0,SETVAL,val);//由于要设置信号量初值,semctl第四个参数为联合体,信号量从0开始      int pid=-1;pid=fork();if(pid<0){perror("fork error");return -1;}else if(pid==0){while(1){sem_p(semid);  //吃面之前先获取资源,如果没有资源应该等待printf("吃了一包面\n");}}else{while(1){sleep(1);printf("生产一包面\n");sem_v(semid); //生产完面释放资源,即此时有资源可以使用,唤醒所有等待的进程}}return 0;
}

这里写图片描述

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. PAT BASIC 1083 是否存在相等的差

    给定 N 张卡片&#xff0c;正面分别写上 1、2、……、N&#xff0c;然后全部翻面&#xff0c;洗牌&#xff0c;在背面分别写上 1、2、……、N。将每张牌的正反两面数字相减&#xff08;大减小&#xff09;&#xff0c;得到 N 个非负差值&#xff0c;其中是否存在相等的差&#…...

    2024/5/2 19:37:55
  2. php学习

    php学习笔记一&#xff0e;变量 1.变量的声明 变量用于储存 数字&#xff0c;文本字符串 或者数组等数据。 注意&#xff1a;在php程序中 使用变量之前是不需要声明的。php中变量必须使用一个美元符号$后面跟着变量名来表示&#xff0c;使用赋值操作符&#xff08;&#xff09;…...

    2024/5/2 20:11:12
  3. 32.最长有效括号

    原题链接 题目描述 给你一个只包含 ‘(’ 和 ‘)’ 的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号子串的长度。 示例 1&#xff1a; 输入&#xff1a;s “(()” 输出&#xff1a;2 解释&#xff1a;最长有效括号子串是 “()” 示例 2&#x…...

    2024/5/2 20:11:08
  4. 2021-2022-1 20212808 《Linux内核原理与分析》第五周作业

    遇到的问题&#xff1a;gdb中单步调试两个命令的区别 gdb中单步调试命令有&#xff1a;s(step)和n(next)。step是逐语句&#xff0c;跳入自定义函数内部执行&#xff1b;而next逐过程&#xff0c;函数直接执行。 系统调用的三层机制&#xff08;下&#xff09; 一、给MenuOS…...

    2024/5/2 20:11:04
  5. 带有下标的双竖线, L0,L1,L2范式

    直接通过举例来说明即可&#xff01;&#xff01;&#xff01;...

    2024/5/2 20:10:59
  6. ./get_datasets.sh 报错 permission denied

    目标&#xff1a;导入 .sh 数据 $ ./get_datasets.sh报错&#xff1a; zsh: permission denied: ./get_datasets.sh原因&#xff1a; .sh没有权限 解决办法&#xff1a;在终端给予权限 $ chmod x get_datasets.sh 再尝试 $ ./get_datasets.sh 即可。 $ 是我的zsh设置终…...

    2024/5/2 20:10:56
  7. wpf调用flash插件报错处理

    在接手的wpf项目中&#xff0c;用到了flash插件&#xff0c;代码编译通过&#xff0c;但是运行起来报错&#xff1a;初始化“AxShockwaveFlashObjects.AxShockwaveFlash”时引发了异常&#xff0c;没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG)) 其实看得出…...

    2024/5/2 20:10:51
  8. 综合案例(体育新闻)-CSS字体、外观属性

    <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>body {font-size: 16px;}/* h1 {font: normal 400 30px "宋体"} */.title {font-size: 30px;font-weight: 400;}.tac {text-align: c…...

    2024/5/2 20:10:48
  9. 中国二正丙胺重点领域需求及未来投资商机研究报告2021-2027年

    中国二正丙胺重点领域需求及未来投资商机研究报告2021-2027年 HSHSHSHSHSHSHSHSHSHS 【撰写单位】&#xff1a;鸿晟信合研究院 第一章二正丙胺行业发展综述 1.1二正丙胺行业定义及分类 1.1.1行业定义 1.1.2行业产品/服务分类 1.1.3行业主要商业模式 1.2二正丙胺行业特征分析 1.…...

    2024/5/2 20:10:43
  10. python报错Ran out of input

    报错显示&#xff1a; 首先进行Traceback&#xff0c;发现报错语句为&#xff1a;pickle.load() 之后网上查找原因有&#xff1a; &#xff08;1&#xff09;https://www.cnblogs.com/rychh/p/9833318.html &#xff08;2&#xff09;https://blog.csdn.net/qq_20373723/artic…...

    2024/5/2 20:10:40
  11. 跟着老猫来搞GO——工欲上其事必先利器

    老猫的GO学习系列博客已经正式发车了&#xff0c;相信大家以前学习一门编程语言的时候也有经验&#xff0c;咱们一般都是从环境开始&#xff0c;在此呢&#xff0c;大家也跟着老猫从最开始的搭建环境开始。 GO语言的安装 首先呢&#xff0c;我们开始需要下载GO语言的安装包。…...

    2024/5/2 20:10:35
  12. 【23考研】计算机择校信息库—北京高校计算机相关专业22专业目录分类汇总(按专业课分类汇总)

    清华大学 计算机科学与技术系 081200计算机科学与技术 ①101 思想政治理论 ②201 英语&#xff08;一&#xff09; ③301 数学&#xff08;一&#xff09; ④912 计算机专业基础综合 912 计算机专业基础综合含数据结构&#xff08;70 分&#xff09;、计算机原理&#xff08;3…...

    2024/5/2 20:10:31
  13. staic的使用

    这节我们只对static进行一点介绍&#xff1a; 注意&#xff1a;关键字是不能创建的&#xff0c;也不能是变量名 1.staic修饰局部变量 可以用来修饰&#xff08;1&#xff09;局部变量 &#xff08;2&#xff09;全局变量 &#xff08;3&#xff09;修饰函数 #include<st…...

    2024/5/2 20:10:28
  14. python

    未完待续...

    2024/5/2 20:10:24
  15. 单链表的相关操作

    按位序插入&#xff08;带头结点&#xff09; #include<stdio.h> #include<stdlib.h>typedef struct LNode {//一个结点带一个数据域和一个指针int data ;struct LNode *next; }LNode,*LinkList; //在第i个位置插入元素e bool ListInsert(LinkList& L, int i,…...

    2024/5/2 20:10:19
  16. Java+MySQL基于springboot+vue的人民医院体检预约系统#毕业设计

    项目编号:JavaMySQL spring230-基于springboot的人民医院体检预约系统#毕业设计 开发语言&#xff1a;Java 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:springbootvue ​现阶段中国人口数量众多&#xff0c;医院体检也将面临种种需要克服…...

    2024/5/2 20:10:16
  17. linux d10 RAID LVM

    近年来&#xff0c;CPU的处理性能保持着高速增长。2017年&#xff0c;Intel公司发布了i9-7980XE处理器芯片&#xff0c;率先让家用电脑达到了18核心36线程。2020年末&#xff0c;AMD公司又推出了“线程撕裂者”系统处理器3990X&#xff0c;家用电脑自此也可以轻松驾驭64核心128…...

    2024/5/2 20:10:11
  18. 汇编语言9---编译链接以及可执行文件

    为什么需要分两步走&#xff0c;编译再链接&#xff08;masm.exe / link.exe&#xff09; 编译 masm asm --> obj 链接 link obj --> exe 假设有100w行代码&#xff0c;编译需要花费一段时间&#xff08;比方说5min&#xff09;。如果代码有错误&#xff0c;修改过后要重…...

    2024/5/2 20:10:09
  19. SQL(表和字段操作)

    一、表层面 1.创建表 CREATE TABLE 表名 ( 字段名 字段属性) CREATE TABLE teacher ( name VARCHAR(10)) 新建表至少含有一个字段 2.删除表 DROP TABLE IF EXISTS 表名 DROP TABLE IF EXISTS teacher 不加if语句可能会报错 3.修改表 ALTER TABLE 表名 RENAME AS 新表名 ALT…...

    2024/5/2 20:10:03
  20. 更换Tomcat默认主页

    Tomcat跑起来后&#xff0c;在浏览器中输入http://localhost:8080/就可以看到Tomcat的默认界面&#xff0c;如下&#xff1a; 默认界面出不来的小朋友请移步&#xff1a;神奇的Tom猫&#xff08;Tomcat&#xff09;手把手教你如何把Tomcat跑起来。 那么问题来了&#xff0c;如…...

    2024/5/2 20:10:00

最新文章

  1. 关于链表带环问题为什么要用快慢指针

    判断链表是否带环 题目描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连…...

    2024/5/4 14:05:02
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. K8S容器空间不足问题分析和解决

    如上图&#xff0c;今天测试环境的K8S平台出现了一个问题&#xff0c;其中的一个容器报错&#xff1a;Free disk space below threshold. Available: 3223552 bytes (threshold: 10485760B)&#xff0c;意思服务器硬盘空间不够了。这个问题怎么产生的&#xff0c;又怎么解决的呢…...

    2024/5/2 2:38:17
  4. Vue ts 如何给 props 中的变量指定特定类型,比如 Interface 类的

    Vue ts 如何给 props 中的变量指定特定类型&#xff0c;比如 Interface 类的 我有一个这样的变量值类型 一、在没用 ts 之前的 props 类型指定方式 我们都知道之前在没用 ts 之前的 props 变量值类型指定方式&#xff1a; 如下图&#xff0c;billFood 定义方式是这样的&…...

    2024/5/2 17:08:55
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/3 23:10:03
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/4 2:59:34
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57