📄 ethernet.c
字号:
#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<sys/wait.h>#include<sys/shm.h>#include<sys/types.h>#include<error.h>#define ERROR_SHMGET -1#define ERROR_SHMAT -2#define ERROR_WAIT -3 #define ERROR_FORK -4#define SLOT_TIME 51.2static unsigned long get_backoff(const int n)//截止二进制指数后退算法的实现{ double exp_rand_slot; unsigned long backoff; int k = n; k = 16-k; if(k>10) k = 10; exp_rand_slot = (1<<k)*random()*SLOT_TIME; backoff = ((unsigned long)exp_rand_slot)%1024; return backoff;}//发送数据流程static void send_msg(const void *addr,const pid_t pid){ pid_t *shm_value = (pid_t*)addr; int i; int collision; for(i = 0; i<10;i++ ) { collision = 16; do { while(*shm_value!=0);//总线不空闲,循环等待 usleep(SLOT_TIME); *shm_value |= pid;//发送数据 usleep(SLOT_TIME); if(*shm_value != pid)//判断是否冲突 { *shm_value = 0;//复原总线为0 collision--; if(collision>0) { printf("%d send collision.\n",pid); usleep(get_backoff(collision));//随机延时 } else { printf("%d send failure.\n",pid);//发送失败 break; } } else { *shm_value = 0; break; } }while(1); if(collision>0) { printf("%d send success.\n",pid); } usleep(random()%1024); }}int main(int arg,char *argv[]){ pid_t pid = 0; //int status = 0; int shmid = 0; void *addr = 0; shmid = shmget(IPC_PRIVATE,sizeof(pid_t),SHM_R|SHM_W);//获取共享内存 if(shmid == -1) { perror("shmget error."); return ERROR_SHMGET; } pid = fork();//创建子进程 if(pid == 0) { pid = getpid();//获取子进程ID addr = shmat(shmid,0,0);//初始化共享内存为/0 if(addr == (void*)-1) { perror("shmat error"); if(shmctl(shmid,IPC_RMID,0) == -1) { perror("shmctl error"); } return ERROR_SHMAT; } srandom(pid); send_msg(addr,pid);//发送数据 } else if(pid>0) { pid = fork(); if(pid == 0) { pid = getpid(); addr = shmat(shmid,0,0); if(addr == (void*)-1) { perror("shmat error"); if(shmctl(shmid,IPC_RMID,0) == -1) perror("shctl error."); return ERROR_SHMAT; } srandom(pid); send_msg(addr,pid); } else if(pid>0) { if(wait(NULL) == -1) { perror("wait error"); return ERROR_WAIT; } else return 0; } else { perror("fork error"); return ERROR_FORK; } } else { perror("fork error"); return ERROR_FORK; } return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -