而阻塞的线程,则唤醒该线程。
互斥变量的定义及初始化如下:
static pthread_mutex_t mtx=PHTREAD_MUTEX_INITIALIZER;
互斥变量的加锁、解锁函数如下: #include
● 加锁:int pthread_mutex_lock(pthread _mutex_t *mutex); ● 解锁:int pthread_mutex_unlock(pthread _mutex_t *mutex); 其中的“mutex”为互斥变量。
【实验内容】
1.实验一
本实验的主要目的是在Linux操作系统中实现多线程程序,并观察多线程执行的情况。 本实验编写一个包含两个线程的程序。程序运行时两个线程分别完成不同的工作:一个线程用于完成从1到10的累加和计算并输出结果(为了便于观察结果,可在每次进行累加的循环中加入一条sleep(1)语句);另一个线程用于不断地从键盘接收用户输入的字符并回显。
操作步骤如下:
1)创建目录“ex12”,然后进入该目录。 # mkdir ex12 # cd ex12
2)使用Vi编辑一个新文件“exam12a.c”,输入源程序。 # vi exam12a.c
其内容如下: #include
int i,sum=0; for(i=1;i<=10;i++) { }
printf(\
//输出累加和结果
sum=sum+i; sleep(1);
//累加
//每次累加后睡眠1秒钟
//函数thread作为求累加和的线程运行
int main(void) { }
//主函数,作为一个线程运行
pthread_t id; int i,ret; char buf[80];
//存放线程id的变量
ret=pthread_create(&id,NULL,(void *) thread,NULL); //创建线程 if(ret!=0) { }
for (i=0;i<10;i++) { }
pthread_join(id,NULL); return (0);
//等待线程的结束
//主线程循环等待用户输入字符并回显
printf (\exit (1);
//创建失败
printf(\scanf(\
printf(\
3)保存“exam12a.c”并退出Vi。
4)在Linux下对源程序“exam12a.c”进行编译。如果编译有错误,则使用vi重新打开源程序进行修改并重新编译,直至编译成功。 # gcc –lpthread –o exam12a exam12a.c
5)执行exam12a。 # ./exam12a
6)观察运行结果,并说明原因。 2.实验二
本实验首先通过观察一个多线程程序中多个线程访问临界资源(公共变量x)时的互斥现象,然后使用互斥变量及其加锁、解锁函数解决互斥。
程序“exam12b.c”是一个多线程互斥的程序。程序包含主函数、“sumx()”以及“setx()”这3个函数。在主函数中将“sumx()”和“setx()”创建为线程运行并等待它们的结束。在线程“sumx()”中循环若干次,将公共变量x累加到sum上;在线程“setx()”中将公共变量x赋值为“0”。编译并运行该程序,观察并分析为什么sum的结果会出错。修改该程序实现互斥。
操作步骤如下:
1)使用Vi编辑一个新文件“exam12b.c”,输入源程序。 # vi exam1b.c
其内容如下: #include
int x=1,sum;
//------函数sumx用于将x累加到sum上------- void sumx(void) {
int i=0; x = 1;
printf(\ for(i=0;i<10000000;i++) {
sum = sum + x; }
printf(\}
//-------函数setx用于将变量x赋值为0-------- void setx(void) {
printf(\ x=0;
printf(\}
int main(void) {
pthread_t id1,id2; int i,ret;
//循环累加
//---创建第一个线程,函数sumx------------
ret=pthread_create(&id1,NULL,(void *) sumx,NULL); if(ret!=0) {
printf (\ exit (1); }
//---创建第二个线程,函数setx------------
ret=pthread_create(&id2,NULL,(void *) setx,NULL); if(ret!=0) {
printf (\ exit (1); }
//---等待两个线程的结束----
pthread_join(id1,NULL); pthread_join(id2,NULL);
printf(\ return (0); }
2)保存“exam12b.c”并退出vi。
3)在Linux下对源程序“exam12b.c”进行编译。 # gcc –lpthread –o exam12b exam12b.c
4)执行exam12b。 # ./exam12b
5)观察运行结果,并说明原因。
6)使用vi打开源程序,修改线程sumx中的循环次数为“10000000”,保存退出vi后重新编译并运行,观察结果,并说明原因。
7)修改源程序,在程序中实现对公共变量x的互斥。