linuxc共享內存
① linux下c的兩個進程如何實現通信一個進程給另一個進程發送消息,另一個接受並顯示出來。求大神啊
linux中的進程通信分為三個部分:低級通信,管道通信和進程間通信IPC(inter process communication)。linux的低級通信主要用來傳遞進程的控制信號——文件鎖和軟中斷信號機制。linux的進程間通信IPC有三個部分——①信號量,②共享內存和③消息隊列。以下是我編寫的linux進程通信的C語言實現代碼。操作系統為redhat9.0,編輯器為vi,編譯器採用gcc。下面所有實現代碼均已經通過測試,運行無誤。
一.低級通信--信號通信
signal.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
/*捕捉到信號sig之後,執行預先預定的動作函數*/
void sig_alarm(int sig)
{
printf("---the signal received is %d. /n", sig);
signal(SIGINT, SIG_DFL); //SIGINT終端中斷信號,SIG_DFL:恢復默認行為,SIN_IGN:忽略信號
}
int main()
{
signal(SIGINT, sig_alarm);//捕捉終端中斷信號
while(1)
{
printf("waiting here!/n");
sleep(1);
}
return 0;
}
二.管道通信
pipe.c
#include <stdio.h>
#define BUFFER_SIZE 30
int main()
{
int x;
int fd[2];
char buf[BUFFER_SIZE];
char s[BUFFER_SIZE];
pipe(fd);//創建管道
while((x=fork())==-1);//創建管道失敗時,進入循環
/*進入子進程,子進程向管道中寫入一個字元串*/
if(x==0)
{
sprintf(buf,"This is an example of pipe!/n");
write(fd[1],buf,BUFFER_SIZE);
exit(0);
}
/*進入父進程,父進程從管道的另一端讀出剛才寫入的字元串*/
else
{
wait(0);//等待子進程結束
read(fd[0],s,BUFFER_SIZE);//讀出字元串,並將其儲存在char s[]中
printf("%s",s);//列印字元串
}
return 0;
}
三.進程間通信——IPC
①信號量通信
sem.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/*聯合體變數*/
union semun
{
int val; //信號量初始值
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
/*函數聲明,信號量定義*/
static int set_semvalue(void); //設置信號量
static void del_semvalue(void);//刪除信號量
static int semaphore_p(void); //執行P操作
static int semaphore_v(void); //執行V操作
static int sem_id; //信號量標識符
int main(int argc, char *argv[])
{
int i;
int pause_time;
char op_char = 'O';
srand((unsigned int)getpid());
sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);//創建一個信號量,IPC_CREAT表示創建一個新的信號量
/*如果有參數,設置信號量,修改字元*/
if (argc > 1)
{
if (!set_semvalue())
{
fprintf(stderr, "Failed to initialize semaphore/n");
exit(EXIT_FAILURE);
}
op_char = 'X';
sleep(5);
}
for(i = 0; i < 10; i++)
{
/*執行P操作*/
if (!semaphore_p())
exit(EXIT_FAILURE);
printf("%c", op_char);
fflush(stdout);
pause_time = rand() % 3;
sleep(pause_time);
printf("%c", op_char);
fflush(stdout);
/*執行V操作*/
if (!semaphore_v())
exit(EXIT_FAILURE);
pause_time = rand() % 2;
sleep(pause_time);
}
printf("/n%d - finished/n", getpid());
if (argc > 1)
{
sleep(10);
del_semvalue(); //刪除信號量
}
exit(EXIT_SUCCESS);
}
/*設置信號量*/
static int set_semvalue(void)
{
union semun sem_union;
sem_union.val = 1;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1)
return(0);
return(1);
}
/*刪除信號量*/
static void del_semvalue(void)
{
union semun sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
fprintf(stderr, "Failed to delete semaphore/n");
}
/*執行P操作*/
static int semaphore_p(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_p failed/n");
return(0);
}
return(1);
}
/*執行V操作*/
static int semaphore_v(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_v failed/n");
return(0);
}
return(1);
}
②消息隊列通信
send.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX_TEXT 512
/*用於消息收發的結構體--my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[MAX_TEXT];
};
int main()
{
int running = 1;//程序運行標識符
struct my_msg_st some_data;
int msgid;//消息隊列標識符
char buffer[BUFSIZ];
/*創建與接受者相同的消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
/*向消息隊列中發送消息*/
while(running)
{
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
some_data.my_msg_type = 1;
strcpy(some_data.some_text, buffer);
if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed/n");
exit(EXIT_FAILURE);
}
if (strncmp(buffer, "end", 3) == 0)
{
running = 0;
}
}
exit(EXIT_SUCCESS);
}
receive.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/*用於消息收發的結構體--my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main()
{
int running = 1;//程序運行標識符
int msgid; //消息隊列標識符
struct my_msg_st some_data;
long int msg_to_receive = 0;//接收消息的類型--0表示msgid隊列上的第一個消息
/*創建消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
/*接收消息*/
while(running)
{
if (msgrcv(msgid, (void *)&some_data, BUFSIZ,msg_to_receive, 0) == -1)
{
fprintf(stderr, "msgrcv failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
printf("You wrote: %s", some_data.some_text);
if (strncmp(some_data.some_text, "end", 3) == 0)
{
running = 0;
}
}
/*刪除消息隊列*/
if (msgctl(msgid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "msgctl(IPC_RMID) failed/n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
③共享內存通信
share.h
#define TEXT_SZ 2048 //申請共享內存大小
struct shared_use_st
{
int written_by_you; //written_by_you為1時表示有數據寫入,為0時表示數據已經被消費者提走
char some_text[TEXT_SZ];
};
procer.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "share.h"
int main()
{
int running = 1; //程序運行標志位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid; //共享內存標識符
/*創建共享內存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmget failed/n");
exit(EXIT_FAILURE);
}
/*將共享內存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個位元組的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed/n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X/n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
/*生產者寫入數據*/
while(running)
{
while(shared_stuff->written_by_you == 1)
{
sleep(1);
printf("waiting for client.../n");
}
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
strncpy(shared_stuff->some_text, buffer, TEXT_SZ);
shared_stuff->written_by_you = 1;
if (strncmp(buffer, "end", 3) == 0)
{
running = 0;
}
}
/*該函數用來將共享內存從當前進程中分離,僅使得當前進程不再能使用該共享內存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed/n");
exit(EXIT_FAILURE);
}
printf("procer exit./n");
exit(EXIT_SUCCESS);
}
customer.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "share.h"
int main()
{
int running = 1;//程序運行標志位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
int shmid; //共享內存標識符
srand((unsigned int)getpid());
/*創建共享內存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmget failed/n");
exit(EXIT_FAILURE);
}
/*將共享內存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個位元組的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed/n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X/n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
shared_stuff->written_by_you = 0;
/*消費者讀取數據*/
while(running)
{
if (shared_stuff->written_by_you)
{
printf("You wrote: %s", shared_stuff->some_text);
sleep( rand() % 4 );
shared_stuff->written_by_you = 0;
if (strncmp(shared_stuff->some_text, "end", 3) == 0)
{
running = 0;
}
}
}
/*該函數用來將共享內存從當前進程中分離,僅使得當前進程不再能使用該共享內存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed/n");
exit(EXIT_FAILURE);
}
/*將共享內存刪除,所有進程均不能再訪問該共享內存*/
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "shmctl(IPC_RMID) failed/n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
摘自:http://blog.csdn.net/piaojun_pj/article/details/5943736
② linux共享內存存在於進程空間的什麼位置
共享內存方式:從物理內存裡面拿出來一部分作為多個進程共享。 共享內存是進程間共享數據的一種最快的方法,一個進程向共享內存區域寫入數據,共享這個內存的所有進程都可以立即看到其中內容。 共享內存實現步驟: 一、創建共享內存,使用shmget函數。 二、映射共享內存,將這段創建的共享內存映射到具體的進程空間去,使用shmat函數。 創建共享內存shmget: intshmget(key_t key, size_t size, int shmflg) 功能:得到一個共享內存標識符或創建一個共享內存對象並返回共享內存標識符。 key: 0(IPC_PRIVATE)會建立共享內存對象 size:大於0的整數,新建共享內存的大小,以位元組為單位。只獲取共享內存時,指定為0. shmflg: 0表示取共享內存標識符,如不存在則函數會報錯; IPC_CREAT,如果內核中不存在鍵值與key相等的共享內存時,則創建一個共享內存;如果存在這樣的共享內存則返回共享內存的標識符; IPC_CREATIPC_EXCL: 如果內核中不存在鍵值與key相等的共享內存,則新建一個消息隊列;如果存在這樣的共享內存則報錯; 函數返回值:成功則返回內存的標識符;出錯則返回-1,錯誤原因存在於error中 映射共享內存到調用進程的地址空間shmat: void*shmat(int shmid, const void *shmaddr, int shmflg) msqid:共享內存標識符 shmaddr:指定共享內存出現在進程內存地址的什麼位置,直接指定為NULL讓內核自己決定一個合適的地址位置。 shmflg: SHM_RDONLY 只讀模式,其他為讀寫模式 函數返回值:成功則返回附加好的共享內存地址;出錯返回-1,錯誤原因存在於error中 斷開共享內存連接shmdt: intshmdt(const void *shmaddr) 功能:傳入shmaddr,連接共享的內存起始地址;斷開成功則返回0,出錯則返回-1,錯誤原因存在於error中。 父子進程間通訊實例: #include #include #include #include #include #include int main(int argc, char **argv){ if(argc< 2){ //需要輸入共享的數據 printf("pleaseinput the shared data.n"); exit(-1); } intshmid; shmid= shmget(0,1024,IPC_CREAT); if(shmid== -1){ // 申請共享內存失敗 printf("createshare memory failed.n"); exit(-1); } if(fork()){ // 父進程之中 char*p_shmaddr; p_shmaddr= shmat(shmid, NULL, 0); // 映射到父進程之中的一個地址 memset(p_shmaddr,0, 1024); // 初始化共享內存 strcpy(p_shmaddr,argv[1]); // 拷貝共享數據到共享內存 wait(NULL); //等待子進程結束 exit(0); } else{ sleep(2); //等待父進程寫入數據 char*c_shmaddr; c_shmaddr= shmat(shmid,NULL,0); // 映射到子進程之中一個地址,具體由kernel 指配 printf("theshare data is: %sn", c_shmaddr); //子進程輸出共享的數據 exit(0); } }
③ linux共享內存的示常式序
代碼 5.1 中的程序展示了共享內存塊的使用。
代碼 5.1 (shm.c) 嘗試共享內存
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main()
{
int segment_id;
char* shared_memory;
struct shmid_ds shmbuffer;
int segment_size;
const int shared_segment_size = 0x6400; /* 分配一個共享內存塊 */
segment_id = shmget(IPC_PRIVATE, shared_segment_size, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR ); /* 綁定到共享內存塊 */
shared_memory = (char*)shmat(segment_id, 0, 0);
printf(shared memory attached at address %p
, shared_memory); /* 確定共享內存的大小 */
shmctl(segment_id, IPC_STAT, &shmbuffer);
segment_size = shmbuffer.shm_segsz;
printf(segment size: %d
, segment_size);
sprintf(shared_memory, Hello, world.); /* 在共享內存中寫入一個字元串 */
shmdt(shared_memory); /* 脫離該共享內存塊 */
shared_memory = (char*)shmat(segment_id, (void*) 0x500000, 0);/* 重新綁定該內存塊 */
printf(shared memory reattached at address %p
, shared_memory);
printf(%s
, shared_memory); /* 輸出共享內存中的字元串 */
shmdt(shared_memory); /* 脫離該共享內存塊 */
shmctl(segment_id, IPC_RMID, 0);/* 釋放這個共享內存塊 */
return 0;
}
④ 怎麼在linux下C語言中將結構體寫入共享內存
隨便怎麼寫啊,共享內存獲取到不是給你一個內存地址,這里稱之為des么,直接通過des地址訪問啊,比如你要寫2個結構體進去,第一個Memcpy寫到des,第二個可以(Memcpy到des+結構體大小)的地址指向的內存上,
⑤ linux下的C語言開發(管道通信)
姓名:馮成 學號:19020100164 學院:丁香二號書院
轉自:https://feixiaoxing.blog.csdn.net/article/details/7229483
【嵌牛導讀】本文將介紹linux下的C語言開發中的管道通信
【嵌牛鼻子】linux C語言 管道通信
【嵌牛提問】linux下的C語言開發中的管道通信是什麼?
Linux系統本身為進程間通信提供了很多的方式,比如說管道、共享內存、socket通信等。管道的使用十分簡單,在創建了匿名管道之後,我們只需要從一個管道發送數據,再從另外一個管道接受數據即可。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int pipe_default[2];
int main()
{
pid_t pid;
char buffer[32];
memset(buffer, 0, 32);
if(pipe(pipe_default) < 0)
{
printf("Failed to create pipe!\n");
return 0;
}
if(0 == (pid = fork()))
{
close(pipe_default[1]);
sleep(5);
if(read(pipe_default[0], buffer, 32) > 0)
{
printf("Receive data from server, %s!\n", buffer);
}
close(pipe_default[0]);
}
else
{
close(pipe_default[0]);
if(-1 != write(pipe_default[1], "hello", strlen("hello")))
{
printf("Send data to client, hello!\n");
}
close(pipe_default[1]);
waitpid(pid, NULL, 0);
}
return 1;
}
下面我們就可以開始編譯運行了,老規矩分成兩步驟進行:(1)輸入gcc pipe.c -o pipe;(2)然後輸入./pipe,過一會兒你就可以看到下面的列印了。
[test@localhost pipe]$ ./pipe
Send data to client, hello!
Receive data from server, hello!
⑥ linux下C語言編程線程有什麼好處呢
進程和線程都是由操作系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的並發性。進程和線程的區別在於:
線程的劃分尺度小於進程,使得多線程程序的並發性搞。
另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。
進程(Process)是最初定義在Unix等多用戶、多任務操作系統環境下用於表示應用程序在內存環境中基本執行單元的概念。以Unix操作系統為例,進程是Unix操作系統環境中的基本成分、是系統資源分配的基本單位。Unix操作系統中完成的幾乎所有用戶管理和資源分配等工作都是通過操作系統對應用程序進程的控制來實現的。
一般你運行一個應用程序,就生成了一個進程, 這個進程擁有自己的內存空間,
這個進程還可以內部生成多個線程, 這些線程之間共用一個進程的內存空存空間,所以線程之間共享內存是很容易做到的,多線程協作比多進程協作快一些,而且安全.
在windows跟unix上面,進程,線程的實現方法都是不一樣的.
⑦ Linux C編程從初學到精通的目 錄
第1部分 基礎篇
第1章 Linux系統概述 1
1.1 什麼是Linux 2
1.2 Linux系統特點及主要功能 2
1.2.1 Linux系統特點 3
1.2.2 Linux系統的主要功能 3
1.3 Linux的內核版本和發行版本 5
1.4 系統的安裝 6
1.4.1 系統安裝前的准備工作 6
1.4.2 從光碟安裝Linux 6
1.4.3 從硬碟安裝Linux 22
1.4.4 在虛擬機下安裝Linux 22
1.5 Shell的使用 27
1.5.1 Shell簡介 27
1.5.2 常見Shell的種類 28
1.5.3 Shell的簡單使用 29
1.5.4 通配符 30
1.5.5 引號 31
1.5.6 注釋符 33
1.6 Linux常用命令 33
1.6.1 與目錄相關的命令 33
1.6.2 與文件相關的命令 34
1.6.3 與網路服務相關的命令 35
1.7 本章小結 35
實戰演練 36
第2章 C語言編程基礎 37
2.1 C語言的歷史背景 38
2.2 C語言的特點 38
2.3 C語言的基本數據類型 39
2.3.1 整型 39
2.3.2 實型 40
2.3.3 字元型 41
2.4 運算符與表達式 43
2.4.1 算術運算符與算術表達式 43
2.4.2 賦值運算符與賦值表達式 44
2.4.3 逗號運算符與逗號表達式 45
2.5 C程序的3種基本結構 46
2.5.1 順序結構 46
2.5.2 選擇結構 47
2.5.3 循環結構 51
2.6 C語言中的數據輸入與輸出 54
2.6.1 字元輸出函數putchar 54
2.6.2 字元輸入函數getchar 54
2.6.3 格式輸出函數printf 54
2.6.4 格式輸入函數scanf 56
2.7 函數 57
2.7.1 函數的定義 57
2.7.2 函數的調用 58
2.7.3 變數的存儲類別 59
2.8 數組 62
2.8.1 一維數組的定義和使用 63
2.8.2 二維數組的定義和使用 64
2.8.3 字元數組和字元串 65
2.8.4 常用字元串處理函數 66
2.9 指針 69
2.9.1 地址和指針 69
2.9.2 指針的定義和使用 70
2.9.3 數組與指針 71
2.9.4 字元串與指針 72
2.9.5 指向函數的指針 72
2.10 結構體和共用體 73
2.10.1 定義和引用結構體 73
2.10.2 結構體數組 74
2.10.3 指向結構體的指針 74
2.10.4 共用體 75
2.10.5 使用typedef定義類型 77
2.11 鏈表 77
2.11.1 鏈表概述 77
2.11.2 建立動態單向鏈表 78
2.11.3 單向鏈表的輸出 80
2.11.4 對單向鏈表的刪除操作 80
2.11.5 對單向鏈表的插入操作 81
2.11.6 循環鏈表 82
2.11.7 雙向鏈表 82
2.12 位運算符和位運算 83
2.12.1 「按位與」運算符(&) 84
2.12.2 「按位或」運算符(|) 84
2.12.3 「取反」運算符(~) 84
2.12.4 「異或」運算符(^) 84
2.12.5 移位運算符(<<和>>) 85
2.12.6 位域 85
2.13 C語言預處理命令 86
2.13.1 宏定義 86
2.13.2 文件包含 87
2.13.3 條件編譯 88
2.13.4 #error等其他常用預處理命令 89
2.14 本章小結 89
實戰演練 89
第3章 vi與Emacs編輯器 91
3.1 vi的使用 92
3.1.1 啟動與退出vi 92
3.1.2 vi的命令行模式 93
3.1.3 vi的插入模式 96
3.1.4 vi的底行模式 96
3.2 vi使用實例 97
3.3 Emacs的使用 100
3.3.1 啟動與退出Emacs 101
3.3.2 Emacs下的基本操作 102
3.4 Emacs使用實例 107
3.5 本章小結 109
實戰演練 109
第4章 gcc編譯器與gdb調試器 110
4.1 gcc編譯器簡介 111
4.2 如何使用gcc 112
4.2.1 gcc編譯初步 112
4.2.2 警告提示功能 114
4.2.3 優化gcc 116
4.2.4 連接庫 119
4.2.5 同時編譯多個源程序 120
4.2.6 管道 120
4.2.7 調試選項 121
4.3 gdb調試器 122
4.3.1 gdb簡介 122
4.3.2 gdb常用命令 123
4.3.3 gdb調試初步 124
4.4 gdb的使用詳解 126
4.4.1 調用gdb 127
4.4.2 使用斷點 127
4.4.3 查看運行時數據 129
4.4.4 查看源程序 133
4.4.5 改變程序的執行 135
4.5 xxgdb調試器簡介 138
4.6 本章小結 139
實戰演練 139
第5章 make的使用和Makefile的編寫 141
5.1 什麼是make 142
5.1.1 make機制概述 142
5.1.2 make與Makefile的關系 144
5.2 Makefile的書寫規則 147
5.2.1 Makefile的基本語法規則 148
5.2.2 在規則中使用通配符 149
5.2.3 偽目標 149
5.2.4 多目標 151
5.2.5 自動生成依賴性 151
5.3 Makefile的命令 152
5.4 變數 154
5.4.1 變數的基礎 154
5.4.2 賦值變數 154
5.4.3 define關鍵字 156
5.4.4 override指示符 156
5.4.5 目標變數和模式變數 157
5.5 常用函數調用 158
5.5.1 字元串處理函數 158
5.5.2 文件名操作函數 162
5.5.3 循環函數 164
5.5.4 條件判斷函數 165
5.5.5 其他常用函數 166
5.6 隱式規則 168
5.6.1 隱式規則舉例 168
5.6.2 隱式規則中的變數 169
5.6.3 使用模式規則 170
5.7 本章小結 173
實戰演練 173
第2部分 提高篇
第6章 文件I/O操作 174
6.1 Linux文件系統簡介 175
6.1.1 Linux的文件系統結構 175
6.1.2 文件類型 176
6.1.3 文件訪問許可權 179
6.2 基於文件描述符的I/O操作 179
6.2.1 文件描述符 180
6.2.2 標准輸入、標准輸出和標准出錯 180
6.2.3 文件重定向 181
6.2.4 文件的創建、打開與關閉 182
6.2.5 文件的定位 186
6.2.6 文件的讀寫 188
6.3 文件的屬性操作 192
6.3.1 改變文件訪問許可權 192
6.3.2 改變文件所有者 193
6.3.3 重命名 193
6.3.4 修改文件長度 194
6.4 文件的其他操作 195
6.4.1 stat、fstat和lstat函數 195
6.4.2 p和p2函數 196
6.4.3 fcntl函數 197
6.4.4 sync和fsync函數 197
6.5 特殊文件的操作 198
6.5.1 目錄文件的操作 198
6.5.2 鏈接文件的操作 201
6.5.3 管道文件的操作 204
6.5.4 設備文件 204
6.6 本章小結 205
實戰演練 205
第7章 基於流的I/O操作 206
7.1 流與緩存 207
7.1.1 流和FILE對象 207
7.1.2 標准輸入、標准輸出和標准出錯 207
7.1.3 緩存 207
7.1.4 對緩存的操作 210
7.2 流的打開與關閉 212
7.2.1 流的打開 212
7.2.2 流的關閉 214
7.2.3 流關閉前的工作 216
7.3 流的讀寫 216
7.3.1 基於字元的I/O 217
7.3.2 基於行的I/O 220
7.3.3 直接I/O 222
7.3.4 格式化I/O 224
7.4 本章小結 226
實戰演練 227
第8章 進程式控制制 228
8.1 進程的基本概念 229
8.1.1 Linux進程簡介 229
8.1.2 進程與作業 230
8.1.3 進程標識 230
8.2 進程式控制制的相關函數 232
8.2.1 fork和vfork函數 232
8.2.2 exec函數 237
8.2.3 exit和_exit函數 242
8.2.4 wait和waitpid函數 245
8.2.5 進程的一生 251
8.2.6 用戶ID和組ID 251
8.2.7 system函數 253
8.3 多個進程間的關系 255
8.3.1 進程組 255
8.3.2 會話期 256
8.3.3 控制終端 257
8.4 本章小結 259
實戰演練 259
第9章 信號 260
9.1 Linux信號簡介 261
9.1.1 信號的基本概念 261
9.1.2 信號處理機制 265
9.2 信號操作的相關函數 267
9.2.1 信號的處理 267
9.2.2 信號的發送 274
9.2.3 信號的阻塞 282
9.2.4 計時器與信號 284
9.3 本章小結 286
實戰演練 287
第10章 進程間通信 288
10.1 進程間通信簡介 289
10.2 管道 290
10.2.1 管道的概念 290
10.2.2 管道的創建與關閉 291
10.2.3 管道的讀寫 292
10.3 命名管道 297
10.3.1 命名管道的概念 297
10.3.2 命名管道的創建 297
10.3.3 命名管道的讀寫 299
10.4 消息隊列 303
10.4.1 消息隊列的概念 303
10.4.2 消息隊列的創建與打開 305
10.4.3 消息隊列的讀寫 306
10.4.4 獲得或設置消息隊列屬性 308
10.5 共享內存 312
10.5.1 共享內存的概念 312
10.5.2 共享內存的相關操作 313
10.6 信號量 318
10.6.1 信號量的概念 319
10.6.2 信號量集的相關操作 320
10.7 本章小結 325
實戰演練 326
第11章 網路編程 327
11.1 網路編程的基礎知識 328
11.1.1 計算機網路體系結構 328
11.1.2 傳輸控制協議TCP 333
11.1.3 用戶數據報協議UDP 335
11.1.4 客戶機/伺服器模式 336
11.2 套介面編程基礎 336
11.2.1 什麼是套介面 337
11.2.2 埠號的概念 338
11.2.3 套介面的數據結構 338
11.2.4 基本函數 340
11.3 TCP套介面編程 343
11.3.1 TCP套介面通信工作流程 343
11.3.2 TCP套介面Client/Server程序實例 356
11.4 UDP套介面編程 360
11.4.1 UDP套介面通信工作流程 360
11.4.2 UDP套介面Client/Server程序實例 362
11.5 原始套介面編程 365
11.5.1 原始套介面的創建 365
11.5.2 原始套介面程序實例 365
11.6 本章小結 376
實戰演練 376
第12章 Linux圖形界面編程 377
12.1 Linux下的圖形界面編程簡介 378
12.1.1 Qt簡介 378
12.1.2 GTK+簡介 378
12.2 界面基本元件 381
12.2.1 一個簡單的例子 381
12.2.2 窗口 383
12.2.3 標簽 385
12.2.4 按鈕 386
12.2.5 文本框 387
12.3 界面布局元件 389
12.3.1 表格 390
12.3.2 框 393
12.3.3 窗格 395
12.4 其他常用元件 398
12.4.1 進度條、微調按鈕、組合框 398
12.4.2 單選按鈕、復選按鈕 402
12.4.3 下拉菜單 404
12.5 信號與回調函數 406
12.6 本章小結 409
實戰演練 409
第3部分 實戰篇
第13章 設計Linux下的計算器 411
13.1 軟體功能分析 412
13.2 程序模塊的劃分 413
13.3 軟體的具體實現 415
13.3.1 頭文件 415
13.3.2 十六進制界面顯示函數 416
13.3.3 十進制界面顯示函數 417
13.3.4 八進制界面顯示函數 418
13.3.5 二進制界面顯示函數 419
13.3.6 進制間轉換函數 420
13.3.7 信號處理模塊 423
13.3.8 主函數 432
13.4 軟體使用效果演示 438
13.5 本章小結 439
第14章 Linux平台下聊天軟體的設計 440
14.1 軟體功能概述 441
14.1.1 伺服器端功能需求 441
14.1.2 客戶端功能需求 442
14.1.3 錯誤處理需求 442
14.2 Glade集成開發工具簡介 443
14.3 軟體功能模塊劃分 444
14.3.1 伺服器功能模塊劃分 444
14.3.2 客戶端功能模塊劃分 445
14.3.3 消息標識的定義 445
14.3.4 消息結構體的設計 446
14.4 伺服器程序的具體實現 447
14.4.1 伺服器消息處理流程 447
14.4.2 伺服器主要函數和變數 448
14.4.3 伺服器消息處理模塊的設計與實現 449
14.4.4 伺服器數據存儲的方法 450
14.4.5 用戶注冊流程 450
14.5 客戶端程序的具體實現 451
14.5.1 客戶端操作流程 451
14.5.2 客戶端發送和接收消息流程 451
14.5.3 客戶端主要函數和變數 452
14.5.4 客戶端功能模塊的設計與實現 453
14.6 聊天軟體使用效果演示 455
14.7 本章小結 459
第15章 Linux遠程管理工具的設計 460
15.1 軟體功能概述 461
15.1.1 Webmin簡介 461
15.1.2 軟體總體設計 461
15.2 伺服器端程序設計 463
15.2.1 伺服器端工作流程 463
15.2.2 系統用戶管理操作 464
15.2.3 系統用戶組的管理操作 466
15.2.4 系統服務啟動管理 468
15.2.5 DNS管理操作 469
15.2.6 Apache服務管理操作 471
15.2.7 FTP服務管理操作 474
15.3 客戶端程序 475
15.3.1 連接界面 475
15.3.2 主界面 477
15.4 本章小結 479
第16章 Linux下簡易防火牆軟體的設計 480
16.1 Netfilter基礎 481
16.1.1 什麼是Netfilter 481
16.1.2 Netfilter的HOOK機制 482
16.1.3 HOOK的調用 485
16.1.4 HOOK的實現 486
16.1.5 IPTables簡介 488
16.1.6 Netfilter可以實現的控制功能 489
16.2 軟體設計概述 491
16.2.1 軟體整體框架 491
16.2.2 管理端的設計 492
16.2.3 控制端的設計 493
16.3 用Netfilter設計控制端功能模塊 495
16.3.1 ICMP管理控制模塊 495
16.3.2 FTP管理控制模塊 497
16.3.3 HTTP管理控制模塊 499
16.3.4 模塊的編譯、載入與卸載 499
16.4 軟體功能測試 501
16.5 本章小結 503
第17章 基於Linux的嵌入式家庭網關遠程交互操作平台的設計 504
17.1 嵌入式技術簡介 505
17.1.1 嵌入式系統的概念 505
17.1.2 嵌入式操作系統 506
17.1.3 嵌入式處理器 507
17.2 家庭網關的概念及其網路體系結構 509
17.2.1 智能家庭網路的概念 509
17.2.2 家庭網關的遠程交互操作技術簡介 510
17.2.3 嵌入式家庭網關的網路體系結構 510
17.3 嵌入式家庭網關的開發平台 511
17.3.1 S3C2410微處理器簡介 511
17.3.2 交叉編譯環境的建立 513
17.4 遠程交互平台的設計 515
17.4.1 應用軟體的開發模式 515
17.4.2 嵌入式Web伺服器 516
17.4.3 通用網關介面CGI 519
17.5 Linux下軟體模塊的具體實現 520
17.5.1 登錄驗證模塊 521
17.5.2 串口通信模塊 521
17.5.3 中央空調控制模塊 522
17.5.4 智能水表數據採集模塊 528
17.5.5 試驗結果 528
17.6 本章小結 529
⑧ linux查看共享內存命令
共享內存查看
使用ipcs命令,不加如何參數時,會把共享內存、信號量、消息隊列的信息都列印出來,如果只想顯示共享內存信息,使用如下命令:
[root@localhost ~]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 1867776 root 600 393216 2 dest
0x00000000 1900545 root 600 393216 2 dest
0x00030021 1703938 zc 666 131104 1
0x0003802e 1736707 zc 666 131104 1
0x00030004 1769476 zc 666 131104 1
0x00038002 1802245 zc 666 131104 1
0x00000000 1933318 root 600 393216 2 dest
0x00000000 1966087 root 600 393216 2 dest
0x00000000 1998856 root 600 393216 2 dest
0x00000000 2031625 root 600 393216 2 dest
0x00000000 2064394 root 600 393216 2 dest
0x0014350c 2261003 cs 666 33554432 2
0x00000000 2129932 root 600 393216 2 dest
0x00000000 2162701 root 600 393216 2 dest
0x00143511 395837454 root 666 1048576 1
其中:
第一列就是共享內存的key;
第二列是共享內存的編號shmid;
第三列就是創建的用戶owner;
第四列就是許可權perms;
第五列為創建的大小bytes;
第六列為連接到共享內存的進程數nattach;
第七列是共享內存的狀態status。其中顯示「dest」表示共享內存段已經被刪除,但是還有用戶在使用它,當該段內存的mode欄位設置為SHM_DEST時就會顯示「dest」。當用戶調用shmctl的IPC_RMID時,內存先查看多少個進程與這個內存關聯著,如果關聯數為0,就會銷毀這段共享內存,否者設置這段內存的mod的mode位為SHM_DEST,如果所有進程都不用則刪除這段共享內存。
⑨ linux下共享內存允許的連接數有限制嗎
對於64位進程,同一進程可連接最多268435456個共享內存段;
對於32位進程,同一進程可連接最多11個共享內存段,除非使用擴展的shmat;
上述限制對於64位應用不會帶來麻煩,因為可供連接的數量已經足夠大了;但對於32位應用,卻很容易帶來意外的問題,因為最大的連接數量只有11個。
下面的常式test02.c演示了這個問題,為了精簡代碼,它反復連接的是同一個共享內存對象;實際上,無論所連接的共享內存對象是否相同,該限制制約的是連接次數:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define MAX_ATTACH_NUM 15
void main(int argc, char* argv[])
{
key_t mem_key;
long mem_id;
void* mem_addr[MAX_ATTACH_NUM];
int i;
if ( ( mem_key = ftok("/tmp/mykeyfile", 1) ) == (key_t)(-1) ) {
printf("Failed to generate shared memory access key, ERRNO=%d\n",
errno);
goto MOD_EXIT;
}
if ( ( mem_id = shmget(mem_key, 256, IPC_CREAT) ) == (-1) ) {
printf("Failed to obtain shared memory ID, ERRNO=%d\n", errno);
goto MOD_EXIT;
}
for ( i=1; i<=MAX_ATTACH_NUM; i++ ) {
if ( ( mem_addr[i] = (void *)shmat(mem_id, 0, 0) ) == (void *)(-1) )
printf("Failed to attach shared memory, times [%02d], errno:%d\n", i,
errno);
else
printf("Successfully attached shared memory, times [%02d]\n", i);
}
MOD_EXIT:
shmctl(mem_id, IPC_RMID, NULL);
}
⑩ linux下的C編程 幫我看看這程序錯誤
/* http://..com/question/15331136.html */
/* 程序在gcc4.03 ubuntu dapper下編譯運行通過 */
/* ahlongxp[at]gmail[dot].com */
#include <sys/types.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>//S_IRUSER等常量
#include <string.h>//memcpy,strlen
int main (int argc,char **argv)
{
int shm_id;
key_t key;
int size;
char *shm_addr,data[64];
if (argc<2)
{
printf("usage:%s command\n",argv[0]);
return -1;
}
size=sizeof (char) * 64;
key = ftok("myshm",0);
shm_id = shmget (key,size,IPC_CREAT|S_IRUSR|S_IWUSR);
if (shm_id==-1)
{
perror("failed to create/get shm");
return -1;
}
switch (argv[1][0])
{
case 'c':
printf ("the shm_id is %d\n",shm_id);
break;
case 'r':
shm_addr = (char*)shmat(shm_id,0,0);
printf ("the shm_id is %d\n",shm_id);
printf ("%s\n",shm_addr);
if(shmdt((void *)shm_addr) == -1)
perror(" detach error ");
break;
case 'w':
shm_addr = (char*)shmat (shm_id,0,0);
memcpy((void*)shm_addr,(void*)argv[2],strlen(argv[2]));
printf("%s\n",data);
if(shmdt((void*)shm_addr) == -1)
perror(" detach error ");
break;
case 'd':
shmctl(shm_id,IPC_RMID,0);
break;
default : printf("error\n");
}
return 0;
}
不管是建立還是訪問,操作步驟是一樣的。你在寫的時候沒有獲得shm_id,所以無論如何也不會成功的。
我的試驗結果是,需要root許可權才能建立或讀取共享內存。
參考資料:
http://www.gbunix.com/htmldata/2006_07/14/20/article_1339_1.html
http://www.chinaunix.net/jh/4/719393.html
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/apis/ipcshmgt.htm
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/apis/ipcshmdt.htm