訊息佇列:預設傳送端將資訊放在前乙個資訊的後面,接收訊息端可以指定接受哪乙個訊息。
1、msgget:建立和開啟乙個訊息佇列
int msgget(key_t key, int msg***)
鍵值,這個鍵值就可以建立不同程序的訊息對列。
引數1:鍵值;引數2:許可權有關
ftok獲得特定的鍵值。
key_t ftok(const char *pathname, int proj_id);
引數1:路徑;引數2:至少是乙個char的子符(非零)
2、msgsnd傳送訊息到訊息佇列
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg***);
引數1:訊息佇列id;引數2:訊息傳送的資訊結構體;引數3:大小(); 引數4:阻塞(0)或非阻塞(ipc_nowait)
struct msgbuf
3、msgrcv 接受訊息從訊息佇列
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msg***);
有用的資訊將來會放在msgp這個結構體的元素(陣列)裡。
msgflag 也是阻塞讀取,意思就是有有訊息就一直讀
msgtyp,選擇0,就是預設先讀取第乙個訊息。
4、訊息佇列是在核心中維護的,用完之後,自己清理
msgctl
引數1:qid;引數2:ipc_rmid;引數:null(不關心詳細的佇列特性)
題目:程序a 和 程序b,通過共享記憶體進行通訊。
ps:shmget注意是建立還是開啟(共享記憶體)
共享記憶體:從真實的物理空間找一段記憶體,對映到我們的虛擬記憶體,在不同程序間的對映記憶體都以為這段記憶體是自己的,這就牽扯到同步。//完成了傳送端的程式
#include
#include
#include
#include
#include
#include
#define size 200
struct msgbuf
; int main(void)
; struct msgbuf msg1 = ;
int ret = -1;
if (key < 0)
else
//建立和開啟乙個訊息佇列
int qid = msgget(key, ipc_creat | 0666);
if (qid < 0)
printf("開啟了乙個訊息佇列qid = %d.\n", qid);
while (1)
ret = msgsnd(qid, &msg, size, 0);
if (ret < 0)
//結束我們程序
if (strncmp(msg.mtext, "quit", 4) == 0)
break;
}return
0;}
1、從實體地址得到確定大小的記憶體
int shmget(key_t key, size_t size, int shm***);
引數1:特殊鍵值 引數2:獲取記憶體大小 3:記憶體的許可權
ps:ipcs -m 專門可以檢視共享記憶體的詳細資訊。
2、刪除共享記憶體
shmctl
3、建立共享
void *shmat(int shmid, const void *shmaddr, int shm***);
引數2:shmaddr == null,表示操作os自動非配乙個未使用而且安全的位址。
引數3shmflag:選則ipc_rdonly唯讀模式,猜測選0是可讀可寫?
4、斷開共享記憶體和所處程序之間的對映關係
int shmdt(const void *shmaddr);
引數:裡面放的是,所處程序中對映過去的有效、合法、未使用位址
訊號:是一種非同步的通訊方式,通訊內容有限制。#include
#include
#include
#include
#include
#include
#define size 2048
int main(void)
; pid_t pid;
//建立共享記憶體
shmid = shmget(ipc_private, size, 0666);
if (shmid < 0)
else
//檢視共享記憶體使用情況
// system("ipcs -m");
//建立程序
pid = fork();
if (pid < 0)
if (pid == 0)
else
//讀父程序的flag是否寫入
while (strncmp(ptr, flag, strlen(flag)))
//讀取父程序有效資料
// strcpy(buf, ptr+strlen(flag));
// printf("子程序得到有效資料[%s].\n", buf);
struct infor
s = ;
//接受結構體資訊
s = *((struct infor *)(ptr+strlen(flag)));
printf("名字:%s, 年齡:%d, 存款:%d.\n", s.name, s.age, s.money);
//子程序分離共享記憶體
if (shmdt(ptr) < 0)
else
printf("子程序分離ok!\n");
// system("ipcs -m");
//刪除共享記憶體
if (shmctl(shmid, ipc_rmid, null) < 0)
printf("子程序刪除成功\n");
}if (pid > 0)
else
printf("父程序寫東西:\n");
//寫正式內容
// fgets(buf, size, stdin);
struct infor
s = ;
// strncpy(ptr+strlen(flag), buf, strlen(buf));
memcpy((struct infor*)(ptr+strlen(flag)), &s, sizeof(s));
strncpy(ptr, flag, strlen(flag));
//父程序分離共享記憶體
if (shmdt(ptr) < 0)
else
printf("父程序分離ok!\n");
// system("ipcs -m");
//父程序等待子程序結束
waitpid(pid, null, 0);
printf("所犯的罪過一切結束了\n");
}#endif
/*
shmctl(5570615, ipc_rmid, null);
shmctl(5603388, ipc_rmid, null);
shmctl(5636157, ipc_rmid, null);
system("ipcs -m");
*/// shmctl(shmid, ipc_rmid, null);
return
0;}
訊號:都是事先編好的一系列int資料
訊號產生方式:
(1)硬體產生
(2)滿足某種軟體需求
(3)硬體異常發生訊號
(4)kill -9
訊號的處理方式:
給誰發的,誰處理
(1)預設處理
(2)捕獲處理 (訊號繫結了乙個函式)
(3)忽略處理
常見的訊號:(路徑:/usr/include/bits/signum.h)
(1)sigint 2 就是平時用到的ctrl+c
(2)sigabrt 6 程式異常終止
(3)sigkill 9 殺死乙個程序(終極方法)
(4)sigsegv 11 無效訪問記憶體
(5)sigalrm 14 鬧鐘訊號
(6)sigchld 17 子程序結束時傳送的訊號
(7)sigstop 19 殺死(暫停)乙個程序ctrl+\
1、安裝訊號函式
raise傳送乙個訊號給當前程序
#include
#include
#include
#include
#include
#include
#include
int main(void)
if (pid == 0)
if (pid > 0)
}waitpid(pid, null, 0);
printf("一切結束.\n");
}//乙個程序發兩個訊號
// while (1);
/*// int i = 4 / 0;
int i;
printf("i = %d.\n", i);
while (1);
*/return
0;}
C語言基礎(十四)gdb除錯
程式設計師在寫程式的時候不可能是一帆風順,一蹴而就的。gcc編譯器可以發現程式 的語法錯誤,但不能發現程式的業務邏輯錯誤,除錯程式是軟體開發的內容之一。除錯程式的方法有很多種,例如可以用printf語句跟蹤列印程式的執行步驟和變數的值,但是太過麻煩。此文章介紹乙個linux系統中強大的除錯工具 gd...
C 基礎 十四
using system using system.collections.generic using system.diagnostics using system.linq using system.text using system.threading using system.threadi...
十四 Go語言基礎之指標
區別於c c 中的指標,go語言中的指標不能進行偏移和運算,是安全指標。任何程式資料載入記憶體後,在記憶體都有他們的位址,這就是指標。而為了儲存乙個資料在記憶體中的位址,我們就需要指標變數。比如,永遠不要高估自己 這句話是我的座右銘,我想把它寫入程式中,程式一啟動這句話是要載入到記憶體 假設記憶體位...