c語言基礎(十四)

2021-08-19 18:43:22 字數 4857 閱讀 9874

訊息佇列:預設傳送端將資訊放在前乙個資訊的後面,接收訊息端可以指定接受哪乙個訊息。

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語言中的指標不能進行偏移和運算,是安全指標。任何程式資料載入記憶體後,在記憶體都有他們的位址,這就是指標。而為了儲存乙個資料在記憶體中的位址,我們就需要指標變數。比如,永遠不要高估自己 這句話是我的座右銘,我想把它寫入程式中,程式一啟動這句話是要載入到記憶體 假設記憶體位...