當前位置:編程學習大全網 - 源碼下載 - linux下c的兩個進程如何實現通信?壹個進程給另壹個進程發送消息,另壹個接受並顯示出來。求大神啊

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];

};

producer.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("producer 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);

}

摘自:/piaojun_pj/article/details/5943736

  • 上一篇:怎麽把真人變成卡通人物
  • 下一篇:大理三月節的發展
  • copyright 2024編程學習大全網