两个进程的代码大抵相同,只有对信号量的处理有一点区别。
第一次的提示显示有的bug😅
思路:每个进程创建一个自己的线程,这个线程根据信号量来决定是否要进入读取内容的判读,如果进入,则开始进行共享内存中是否有内容,有就取出来,没有就进行下一次的循环。
结果
a进程源码
#include <stdio.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
#define SHM_SIZE 128
char *p = NULL;
sem_t *sem1 = NULL, *sem2 = NULL;
void fun(int signo)
{
shmdt(p); // 取消对共享空间的映射
sem_close(sem1); // 关闭信号量,内核中没有删除
sem_close(sem2);
sem_unlink("zlk"); // 删除信号量
exit(0);
return ;
}
void *jieshou(void *arg)
{
while(1)
{
// 在阻塞的时候无操作
sem_wait(sem1);
if(*p != 0)
{
//printf("收到:%s\r\n", p);
printf("收到:%s", p);
memset(p, 0, sizeof(SHM_SIZE));
}
}
}
int main(int argc, char *argv[])
{
// 信号量部分
sem1 = sem_open("shou", O_CREAT, 0666, 0); // 设置信号量sem1的初始化值为0
if(SEM_FAILED == sem1) // 判断信号量是否创建成功
{
perror("sem_open error");
return -1;
}
sem2 = sem_open("fa", O_CREAT, 0666, 0);
if(SEM_FAILED == sem2) // 判断信号量是否创建成功
{
perror("sem_open error");
return -1;
}
// 共享内存部分
key_t key = ftok(".", 22);
if(-1 == key)
{
perror("ftok error");
return -1;
}
int shmId = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 生成一个共享空间
if(-1 == shmId)
{
perror("shmget error");
return -1;
}
p = (char *)shmat(shmId, NULL, 0); // 在私有空间中建立共享内存的映射
if((void *)-1 == p)
{
perror("shmat error");
return -1;
}
memset(p, 0, sizeof(SHM_SIZE)); // 清空原先空间里的内容
printf("--------zlk------------\r\n");
// 创建一个线程,用于监听收到的信息
pthread_t tID = -1;
if(0 != pthread_create(&tID, NULL, jieshou, NULL))
{
printf("creater pthread error\r\n");
return -1;
}
while(1)
{
signal(SIGINT, fun); // 收到Ctrl + c后调用自定义fun函数
printf("发送:\r\n");
fgets(p, SHM_SIZE, stdin);
sem_post(sem2); // 使sem2加1
}
return 0;
}
b进程源码
#include <stdio.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
#define SHM_SIZE 128
char *p = NULL;
sem_t *sem1 = NULL, *sem2 = NULL;
void fun(int signo)
{
shmdt(p); // 取消对共享空间的映射
sem_close(sem1); // 关闭信号量,内核中没有删除
sem_close(sem2);
sem_unlink("zlk"); // 删除信号量
exit(0);
return ;
}
void *jieshou(void *arg)
{
while(1)
{
sem_wait(sem2);
if(*p != 0)
{
printf("收到:%s", p);
memset(p, 0, sizeof(SHM_SIZE));
}
}
}
int main(int argc, char *argv[])
{
// 信号量部分
sem1 = sem_open("shou", O_CREAT, 0666, 0); // 设置信号量sem1的初始化值为0
if(SEM_FAILED == sem1) // 判断信号量是否创建成功
{
perror("sem_open error");
return -1;
}
sem2 = sem_open("fa", O_CREAT, 0666, 0);
if(SEM_FAILED == sem2) // 判断信号量是否创建成功
{
perror("sem_open error");
return -1;
}
// 共享内存部分
key_t key = ftok(".", 22);
if(-1 == key)
{
perror("ftok error");
return -1;
}
int shmId = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 生成一个共享空间
if(-1 == shmId)
{
perror("shmget error");
return -1;
}
p = (char *)shmat(shmId, NULL, 0); // 在私有空间中建立共享内存的映射
if((void *)-1 == p)
{
perror("shmat error");
return -1;
}
printf("--------ylx------------\r\n");
// 创建一个线程,用于监听收到的信息
pthread_t tID = -1;
if(0 != pthread_create(&tID, NULL, jieshou, NULL))
{
printf("creater pthread error\r\n");
return -1;
}
while(1)
{
signal(SIGINT, fun); // 收到Ctrl + c后调用自定义fun函数
printf("发送:\r\n");
fgets(p, SHM_SIZE, stdin);
sem_post(sem1); // 使sem1加1
}
return 0;
}