实验报告封面:
进入 exp/basic/02_pthread 目录,使用vi 编辑器或其他编辑器阅读理解源代码。
在超级终端中运行可执行文件pthread,结果如图:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "pthread.h"
#define BUFFER_SIZE 16
/* 设置一个整数的圆形缓冲区 */
struct prodcons {
int buffer[BUFFER_SIZE]; /* 缓冲区数组 */
pthread_mutex_t lock; /* 互斥锁 */
int readpos, writepos; /* 读写的位置*/
pthread_cond_t notempty; /* 缓冲区非空信号 */
pthread_cond_t notfull; /*缓冲区非满信号 */
};
/*--------------------------------------------------------*/
/*初始化缓冲区*/
void init(struct prodcons * b)
{
pthread_mutex_init(&b->lock, NULL);
pthread_cond_init(&b->notempty, NULL); //条件变量初始化
pthread_cond_init(&b->notfull, NULL);
b->readpos = 0;
b->writepos = 0;
}
/*--------------------------------------------------------*/
/* 生产者写入共享的循环缓冲区函数 PUT,向缓冲区中写入一个整数*/
void put(struct prodcons * b, int data)
{
pthread_mutex_lock(&b->lock); //获取互斥锁
/*等待缓冲区非满*/
while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {
printf("wait for not full\n");
pthread_cond_wait(&b->notfull, &b->lock); //等待状态变量b->notfull,不满则跳出阻塞
}
/*写数据并且指针前移*/
b->buffer[b->writepos] = data; //写入数据
b->writepos++;
if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
/*设置缓冲区非空信号*/
pthread_cond_signal(&b->notempty); //设置状态变量
pthread_mutex_unlock(&b->lock); //释放互斥锁
}
/*--------------------------------------------------------*/
/*消费者读取共享的循环缓冲区函数 GET,从缓冲区中读出一个整数 */
int get(struct prodcons * b)
{
int data;
pthread_mutex_lock(&b->lock); //获取互斥锁
/* 等待缓冲区非空*/
while (b->writepos == b->readpos) { //如果读写位置相同
printf("wait for not empty\n");
pthread_cond_wait(&b->notempty, &b->lock); //等待状态变量,不空则跳出阻塞。否则无数据可读。
}
/* 读数据并且指针前移 */
data = b->buffer[b->readpos]; //读取数据
b->readpos++;
if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
/* 设置缓冲区非满信号*/
pthread_cond_signal(&b->notfull); //设置状态变量
pthread_mutex_unlock(&b->lock); //释放互斥锁
return data;
}
/*--------------------------------------------------------*/
#define OVER (-1)
struct prodcons buffer;
/*--------------------------------------------------------*/
void * producer(void * data)
{
int n;
for (n = 0; n < 1000; n++) {
printf(" put-->%d\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
printf("producer stopped!\n");
return NULL;
}
/*--------------------------------------------------------*/
void * consumer(void * data)
{
int d;
while (1) {
d = get(&buffer);
if (d == OVER ) break;
printf(" %d-->get\n", d);
}
printf("consumer stopped!\n");
return NULL;
}
/*--------------------------------------------------------*/
int main(void)
{
pthread_t th_a, th_b;
void * retval;
init(&buffer);
pthread_create(&th_a, NULL, producer, 0); //线程创建函数
pthread_create(&th_b, NULL, consumer, 0);
/* 等待生产者和消费者结束 */
pthread_join(th_a, &retval); //等待指定的线程结束
pthread_join(th_b, &retval);
return 0;
}
#include <termios.h> /*PPSIX 终端控制定义*/
#include <stdio.h> /*标准输入输出定义*/
#include <unistd.h> /*linux 标准函数定义*/
#include <fcntl.h> /*文件控制定义*/
#include <sys/signal.h>
#include <pthread.h> /*线程库定义*/
#define BAUDRATE B115200
#define COM1 "/dev/ttyS0"
#define COM2 "/dev/ttyS1"
#define ENDMINITERM1 27 /* ESC to quit miniterm */
#define ENDMINITERM2 3 /*ctl +c to quit miniterm */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
volatile int fd;
void child_handler(int s)
{
printf("stop!!!\n");
STOP=TRUE;
}
/*--------------------------------------------------------*/
void* keyboard(void * data)
{
int c;
for (;;){
c=getchar();
// printf("getchar is :%d",c);
if( (c== ENDMINITERM1) | (c==ENDMINITERM2)){
STOP=TRUE;
break ;
}
}
return NULL;
}
/*--------------------------------------------------------*/
/* modem input handler */
void* receive(void * data)
{
int c;
printf("read modem\n");
while (STOP==FALSE)
{
read(fd,&c,1); /* com port */
write(1,&c,1); /* stdout */
}
printf("exit from reading modem\n");
return NULL;
}
/*--------------------------------------------------------*/
void* send(void * data)
{
int c='0';
printf("send data\n");
while (STOP==FALSE)
{
c++;
c %= 255;
write(fd,&c,1); /* stdout */
usleep(100000);
}
return NULL; /* wait for child to die or it will become a zombie */
}
/*--------------------------------------------------------*/
int main(int argc,char** argv)
{
struct termios oldtio,newtio,oldstdtio,newstdtio;
struct sigaction sa;
int ok;
pthread_t th_a, th_b, th_c;
void * retval;
if( argc > 1)
fd = open(COM2, O_RDWR ); /*以读写方式打开串口*/
else
fd = open(COM1, O_RDWR ); //| O_NOCTTY |O_NONBLOCK);
if (fd <0) { /* 不能打开串口一*/
perror(COM1);
exit(-1);
}
tcgetattr(0,&oldstdtio);
tcgetattr(fd,&oldtio); /* save current modem settings */
tcgetattr(fd,&newstdtio); /* get working stdtio */
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* 控制模式标志 */
newtio.c_iflag = IGNPAR; /* 输入模式标志 */
newtio.c_oflag = 0; /* 输出模式标志 */
newtio.c_lflag = 0; /* local mode flags */
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
/* now clean the modem line and activate the settings for modem */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);/*set attrib */
sa.sa_handler = child_handler;
sa.sa_flags = 0;
sigaction(SIGCHLD,&sa,NULL); /* handle dying child */
pthread_create(&th_a, NULL, keyboard, 0);
pthread_create(&th_b, NULL, receive, 0);
pthread_create(&th_c, NULL, send, 0);
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
pthread_join(th_c, &retval);
tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */
tcsetattr(0,TCSANOW,&oldstdtio); /* restore old tty setings */
close(fd);
exit(0);
}
#include <stdio.h> /*标准输入输出定义*/
#include <unistd.h> /*linux 标准函数定义*/
#include <fcntl.h> /*文件控制定义*/
#include <errno.h> /*错误号定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
int main()
{
int fd,n;
char buf[256];
fd=open("/dev/ttyS1",O_NOCTTY|O_RDWR|O_NONBLOCK); /*以读写方式打开串口*/
if( fd < 0) /* 不能打开串口一*/
{
perror("Unable open /dev/ttyS0\r ");
return 1;
}
n = write( fd, "hello\r", 6);
if ( n < 0 )
puts( "write() of 6 bytes failed!\r");
puts( "write() of 6 bytes ok!\r");
while(1)
{
read(fd,buf,256);
puts(buf);
if(strncmp(buf,"quit",4)==0)break;
}
return 0;
}
int set_port(int fd)
{
struct termios opt;
tcgetattr(fd,&opt);/*get current option setup*/
show_option(&opt);
// opt.c_cflags &=
tcsetattr(fd,&opt);/*get current option setup*/
}
解决方法:检查之前的开发环境配置部分,发现是环境变量path设置错误的缘故,导致之后使用编译命令时找不到这条命令。将环境变量PATH改为PATH=$PATH:$HOME/bin:/opt/host/armv4l/bin/ 后就能顺利完成编译。
解决方法:在编译命令前添加待编译的文件所在具体路径则可编译成功。
《信息安全系统设计基础实验图文教程》
《2410经典实验指导20110331》
《如何建立Linux下的ARM交叉编译环境》http://www.cnblogs.com/joeblackzqq/archive/2011/05/17/2048696.html