(写的不好,很不好,意在说明共享内存)
无聊的共享内存
一.简介
本列程是由1.3附属程序的进程版,使用了共享内存来实现(自写)
二.重点掌握函数:
无新函数
三.要求水平
可使用共享内存内来进行进程通信。
四.由于使用了前面所用到的程序所以没有加备注。
#include <stdio.h>
#include <stddef.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#define PWM_IOCTL_SET_FREQ 1
#define PWM_IOCTL_STOP 0
#define ESC_KEY 0x1b
pthread_mutex_t mutex;
static int fd = -1;
static void close_buzzer(void);
void open_led(int on,int led_on);
int led_ons(int leds,char i);
void delay(int times);
typedef struct{int age;
} people;
void reader_function(people *p_data);
void writer_function(people *p_data);
static int getch(void)
{
struct termios oldt,newt;
int ch;
if (!isatty(STDIN_FILENO)) {
fprintf(stderr, "this problem should be run at a terminal\n");
exit(1);
}
// save terminal setting
if(tcgetattr(STDIN_FILENO, &oldt) < 0) {
perror("save the terminal setting");
exit(1);
}
// set terminal as need
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) < 0) {
perror("set terminal");
exit(1);
}
ch = getchar();
// restore termial setting
if(tcsetattr(STDIN_FILENO,TCSANOW,&oldt) < 0) {
perror("restore the termial setting");
exit(1);
}
return ch;
}
static void open_buzzer(void)
{
fd = open("/dev/pwm", 0);
if (fd < 0) {
perror("open pwm_buzzer device");
exit(1);
}
// any function exit call will stop the buzzer
atexit(close_buzzer);
}
static void close_buzzer(void)
{
if (fd >= 0) {
ioctl(fd, PWM_IOCTL_STOP);
close(fd);
fd = -1;
}
}
static void set_buzzer_freq(int freq)
{
// this IOCTL command is the key to set frequency
int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq);
if(ret < 0) {
perror("set the frequency of the buzzer");
exit(1);
}
}
static void stop_buzzer(void)
{
int ret = ioctl(fd, PWM_IOCTL_STOP);
if(ret < 0) {
perror("stop the buzzer");
exit(1);
}
}
int main()
{
int shm_id,i;
key_t key;
people *p_map;
pthread_mutex_init(&mutex,NULL);
char* name = "/dev/shm/myshm2";
key = ftok(name,0);
if(key==-1)
perror("ftok error");
shm_id=shmget(key,4096,IPC_CREAT);
if(shm_id==-1)
{
perror("shmget error");
return;
}
p_map=(people*)shmat(shm_id,NULL,0);
int pid=fork();
if(pid < 0)
{
printf("error!");
}
else
if(pid==0)
{
writer_function(p_map);
if(shmdt(p_map) == -1)
perror(" detach error ");
}
else
{
reader_function(p_map);
if(shmdt(p_map)==-1)
perror(" detach error ");
}
}
void writer_function(people *p_data)
{
int last;
int off;
int led_on=-1;
int f_led;
// float dl;
while(1)
{
off=1;
led_on++;
if(led_on==4)
{
led_on=0;
}
open_led(1,led_on);
for(f_led=3;f_led>0;f_led--)
{
last=led_ons(led_on,off);
open_led(0,last);
off++;
}
pthread_mutex_lock(&mutex);
delay((p_data->age)*8);
// dl=((p_data->age)/2000;
// sleep(dl);
pthread_mutex_unlock(&mutex);
}
}
void reader_function(people *p_data)
{
int freq = 1000 ;
open_buzzer();
printf( "\nBUZZER TEST ( PWM Control )\n" );
printf( "Press +/- to increase/reduce the frequency of the BUZZER\n" ) ;
printf( "Press 'ESC' key to Exit this program\n\n" );
while(1)
{
int key;
set_buzzer_freq(freq);
pthread_mutex_lock(&mutex);
p_data->age=((21000-freq)/10);
pthread_mutex_unlock(&mutex);
printf( "\tFreq = %d\n", freq );
key = getch();
switch(key)
{
case '+':
if( freq < 20000 )
freq += 10;
break;
case '-':
if( freq > 11 )
freq -= 10 ;
break;
case ESC_KEY:
case EOF:
stop_buzzer();
exit(0);
default:
break;
}
}
}
void open_led(int on,int led_on)
{
int ss;
ss= open("/dev/leds0", 0);
if (ss< 0)
{
ss= open("/dev/leds", 0);
}
if (ss< 0)
{
perror("open device leds");
exit(1);
}
/*通过系统调用 ioctl 和输入的参数控制 led*/
ioctl(ss, on, led_on);
/*关闭设备句柄*/
close(ss); //delete????????
}
int led_ons(int leds,char i)
{
int a;
a=leds;
for(i;i>0;i--)
{
a++;
if(a==4)
{a=0;}
}
return a;
}
void delay(int times)
{
int i;
for(;times>0;times--)
for(i=0;i<400;i++);
}