目錄題目思路代碼展示進程A進程B結果展示 題目 要求進程A創建一條消息隊列之後向進程B發送SIGUSR1信號,進程B收到該信號之後打開消息隊列並寫入一段信息作為消息寫入到消息隊列中,要求進程B在寫入消息之後,發SIGUSR2信號給進程A,進程A收到該信號則從消息隊列中讀取消息並輸出消息正文的內容。 ...
目錄
題目
要求進程A創建一條消息隊列之後向進程B發送SIGUSR1信號,進程B收到該信號之後打開消息隊列並寫入一段信息作為消息寫入到消息隊列中,要求進程B在寫入消息之後,發SIGUSR2信號給進程A,進程A收到該信號則從消息隊列中讀取消息並輸出消息正文的內容。
思路
- 通過進程A創建的消息隊列,實現進程A與進程B之間的PID交換
- 通過kill指令完成進程A與進程B之間的信號交互,並通過狀態機實現步驟的進行
- 進程A收到進程B的信號後,從消息隊列中讀出消息,並完成顯示
代碼展示
進程A
/*******************************************************************
*
* file name: process_A.c
* author : [email protected]
* date : 2024/05/27
* function : 該案例是掌握進程通信方式,主要是學習信號和消息隊列的使用
* note : None
* version :
*
* CopyRight (c) 2023-2024 [email protected] All Right Reseverd
*
* *****************************************************************/
/****************************頭文件**************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <unistd.h>
/****************************結構體**************************************/
struct msgbuf
{
long mtype; /* message type, must be > 0 */
int mtext; /* message data */
};
/****************************全局變數**************************************/
volatile int flag; //作為狀態機條件
/********************************************************************
*
* name : msg_get
* function : 改函數用於獲取進程B發送的信號
* pqram :
* @signum : 捕捉到的信號類型
*
* retval : none
* author : [email protected]
* date : 2024/05/27
* note : none
* version :
*
* *****************************************************************/
void msg_get(int signum)
{
if(signum == SIGUSR1)
{
//改變標誌量,從消息隊列中讀取進程B的pid
flag = 1;
}
else if(signum == SIGUSR2)
{
//改變標誌量,從消息隊列中讀取進程B發送的消息
flag = 0;
}
}
int main(int argc, char const *argv[])
{
//捕捉進程B發送的信號,再從消息隊列中獲取進程B的pid
signal(SIGUSR1, msg_get);
//捕捉進程B發送的信號,再從消息隊列中獲取進程B發送的消息
signal(SIGUSR2, msg_get);
/****創建一條消息隊列****/
//1) 獲取消息隊列唯一鍵值(key)
key_t key = ftok(".", 0xffffff01);
//2) 定義一個變數用於存儲消息隊列id,創建一條消息隊列
int msg_id = msgget(key, IPC_CREAT | 0644);
if(msg_id == -1)
{
fprintf(stderr, "msgget error , errno: %d, %s\n", errno, strerror(errno));
exit(-1);
}
/****發送SIGUSR1信號給進程B****/
// 通過消息隊列完成A,B進程的pid交換
//1. 將進程A的pid寫入消息隊列中
struct msgbuf msg_pid;
msg_pid.mtype = 1;
msg_pid.mtext = getpid();
msgsnd(msg_id, &msg_pid, 4, 0);
//2. 捕捉進程B發送的SIGUSR1信號
while(flag == 0);
// 3. 從消息隊列中讀取進程B的pid
struct msgbuf msg_pid_B;
msgrcv(msg_id, &msg_pid_B, 4, 1, IPC_NOWAIT);
//4. 發送SIGUSR1信號給進程b
kill(msg_pid_B.mtext, SIGUSR1);
/****接收到進程B的信號後,從消息隊列中讀出消息並輸出****/
while(flag);
struct msgbuf msg_num;
msgrcv(msg_id, &msg_num, 4, 2, IPC_NOWAIT);
printf("The information received from process B is %d\n", msg_num.mtext);
return 0;
}
進程B
/*******************************************************************
*
* file name: process_B.c
* author : [email protected]
* date : 2024/05/27
* function : 該案例是掌握進程通信方式,主要是學習信號和消息隊列的使用
* note : None
* version :
*
* CopyRight (c) 2023-2024 [email protected] All Right Reseverd
*
* *****************************************************************/
/****************************頭文件**************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <unistd.h>
/****************************結構體**************************************/
struct msgbuf
{
long mtype; /* message type, must be > 0 */
int mtext; /* message data */
};
/****************************全局變數**************************************/
volatile int flag = 1; //作為狀態機條件
/********************************************************************
*
* name : msg_get
* function : 改函數用於獲取進程A發送的信號
* pqram :
* @signum : 捕捉到的信號類型
*
* retval : none
* author : [email protected]
* date : 2024/05/27
* note : none
* version :
*
* *****************************************************************/
void msg_get(int signum)
{
if(signum == SIGUSR1)
{
//改變標誌量,從消息隊列中讀取進程A的pid
flag = 0;
}
}
int main(int argc, char const *argv[])
{
//捕捉進程A發送的信號,再從消息隊列中獲取進程B的pid
signal(SIGUSR1, msg_get);
/****打開一條消息隊列****/
//1) 獲取消息隊列唯一鍵值(key)
key_t key = ftok(".", 0xffffff01);
//2) 定義一個變數用於存儲消息隊列id,創建一條消息隊列
int msg_id = msgget(key, IPC_CREAT | 0644);
if(msg_id == -1)
{
fprintf(stderr, "msgget error , errno: %d, %s\n", errno, strerror(errno));
exit(-1);
}
struct msgbuf msg_pid_a;
/****從消息隊列中讀取進程A的pid,並將進程B的pid寫入消息隊列中***/
msgrcv(msg_id, &msg_pid_a, 4, 1, IPC_NOWAIT);
//將進程B的pid寫入消息隊列
struct msgbuf msg_pid_b;
msg_pid_b.mtype = 1;
msg_pid_b.mtext = getpid();
msgsnd(msg_id, &msg_pid_b, 4, 0);
/****發送SIGUSR1信號給進程A****/
kill(msg_pid_a.mtext, SIGUSR1);
/****等待接收進程A的SIGUSR1信號****/
while(flag == 1);
/****接收到進程A的信號後,將數據寫入消息隊列中***/
struct msgbuf msg_num;
msg_num.mtype = 2;
msg_num.mtext = 66666;
msgsnd(msg_id, &msg_num, 4, 0);
/****發送SIGUSR2信號給進程A****/
kill(msg_pid_a.mtext, SIGUSR2);
return 0;
}