当前位置: 代码迷 >> 综合 >> Linux_信号量实现进程间通信
  详细解决方案

Linux_信号量实现进程间通信

热度:52   发布时间:2023-10-24 23:40:07.0

目录

知识点1【无名信号量完成 有血缘关系的进程间 互斥】

总结:

知识点2【有名信号量 没有血缘进程互斥】

1、创建一个有名信号量

2、信号量的关闭:

3、信号量文件的删除

4、P操作 sem_wait V操作sem_post 销毁信号量sem_destroy

知识点3【有名信号量 没有血缘进程同步】


知识点1【无名信号量完成 有血缘关系的进程互斥

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/mman.h>void myPrintf(char *str){while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}int main(int argc, char const *argv[])
{//互斥 只需要 定义一个信号量sem_t *sem;//匿名映射mmap MAP_ANONYMOUS  -1不用打开文件sem = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);//信号量 sem 初始化 第一个1表示进程间同步互斥  第二个1信号量的初始值1sem_init(sem, 1, 1);pid_t pid = fork();if(pid == 0){//子进程//p 操作-1sem_wait(sem);myPrintf("hello");//v 操作+1sem_post(sem);}else if(pid > 0){//父进程sem_wait(sem);myPrintf("world");sem_post(sem);}getchar();//销毁信号量sem_destroy(sem);//销毁mmapmunmap(sem, sizeof(sem_t));return 0;
}brightsky@Bright-SKY:~/codes/blog$ ./a.out 
worldhello

总结:

无名信号量 (sem_t sem) 线程同步互斥。

无名信号量(mmap 匿名映射) 有血缘关系的进程同步互斥

有名信号量 无血缘关系的进程同步互斥

知识点2【有名信号量 没有血缘进程斥】

1、创建一个有名信号量

 #include <fcntl.h>           /* For O_* constants */#include <sys/stat.h>        /* For mode constants */#include <semaphore.h>//信号量存在
sem_t *sem_open(const char *name, int oflag);
//信号量不存在
sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);

功能:

        创建一个信号量

参数:

        name:信号量的名字

        oflag:sem_open函数的权限标志

        mode:文件权限(可读、可写、可执行 0777)的设置

        value:信号量的初始值

返回值:

        信号量的地址,失败:SEM_FAILED

2、信号量的关闭:

int sem_close(sem_t *sem);

功能:关闭信号量

参数:信号量的的地址

返回值:成功0 失败-1

3、信号量文件的删除

#include <semaphore.h>
int sem_unlink(const char *name);

功能:删除信号量的文件

参数:信号量的文件名

返回值:成功0 失败-1

4、P操作 sem_wait V操作sem_post 销毁信号量sem_destroy

04_fork01.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//互斥需要一个信号量sem_t *sem = sem_open("sem", O_RDWR|O_CREAT,0666,1);//p操作-1sem_wait(sem);myPrintf("hello hehe haha");//v操作+1sem_post(sem);//关闭信号量sem_close(sem);return 0;
}

04_fork02.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//互斥需要一个信号量sem_t *sem = sem_open("sem", O_RDWR|O_CREAT,0666,1);//p操作-1sem_wait(sem);myPrintf("world xixi lala");//v操作+1sem_post(sem);//关闭信号量sem_close(sem);return 0;
}

运行结果:编译的时候记得加-lpthread

知识点3【有名信号量 没有血缘进程同步

04_fork01.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//同步需要2个信号量sem_t *sem1 = sem_open("sem1", O_RDWR|O_CREAT,0666,1);sem_t *sem2 = sem_open("sem2", O_RDWR|O_CREAT,0666,0);//p操作-1sem_wait(sem1);myPrintf("hello hehe haha");//v操作+1sem_post(sem2);//关闭信号量sem_close(sem1);sem_close(sem2);return 0;
}

04_fork02.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<fcntl.h>void myPrintf(char *str)
{while(*str != 0){printf("%c", *str);fflush(stdout);str++;sleep(1);}
}
int main()
{//同步需要2个信号量sem_t *sem1 = sem_open("sem1", O_RDWR|O_CREAT,0666,1);sem_t *sem2 = sem_open("sem2", O_RDWR|O_CREAT,0666,0);//p操作-1sem_wait(sem2);myPrintf("world xixi lala");//v操作+1sem_post(sem1);//关闭信号量sem_close(sem1);sem_close(sem2);return 0;
}

  相关解决方案