线程实验七:linux多线程编程(实验报告)

linux多线程编程  时间:2021-01-19  阅读:()

实验七 Linux多线程编程4课时

实验目的掌握线程的概念熟悉Linux下线程程序编译的过程掌握多线程程序编写方法。

实验原理为什么有了进程的概念后还要再引入线程呢使用多线程到底有哪些好处什么的系统应该选用多线程我们首先必须回答这些问题。

1多线程概念

使用多线程的理由之一是和进程相比它是一种非常"节俭"的多任务操作方式。运行于一个进程中的多个线程它们彼此之间使用相同的地址空间共享大部分数据启动一个线程所花费的空间远远小于启动一个进程所花费的空间。使用多线程的理由之二是线程间方便的通信机制。同一进程下的线程之间共享数据空间所以一个线程的数据可以直接为其它线程所用这不仅快捷而且方便。2多线程编程函数

Linux系统下的多线程遵循POSIX线程接口称为pthread。编写Linux下的多线程程序需要使用头文件pthread.h 连接时需要使用库l ibpthread.a。pthread_t在头文件/usr/include/bits/pthreadtypes.h中定义typedef unsigned long int pthread_t;它是一个线程的标识符。

函数p th re a d_c re a te用来创建一个线程它的原型为extern int pthread_create((pthread_t *thread,const pthread_attr_t *attr,void*(*start_routine) (void*),void*arg));

第一个参数为指向线程标识符的指针第二个参数用来设置线程属性第三个参数是线程运行函数的起始地址最后一个参数是运行函数的参数。

函数pthread_join用来等待一个线程的结束。函数原型为

精品资料

extern int pthread_jo in(pthread_t th,vo id**thread_return);

第一个参数为被等待的线程标识符第二个参数为一个用户定义的指针它可以用来存储被等待线程的返回值。

函数pthread_exit的函数原型为extern void pthread_exit(vo id*retval);

唯一的参数是函数的返回代码只要pth read_join中的第二个参数thread_retu rn 不是N U LL 这个值将被传递给thread_return。

3修改线程的属性

线程属性结构为pthread_attr_t 它在头文件/usr/include/pthread.h中定义。属性值不能直接设置须使用相关函数进行操作初始化的函数为pthread_attr_in it 这个函数必须在p th re a d_c re a te函数之前调用。

设置线程绑定状态的函数为pth read_attr_setscope 它有两个参数第一个是指向属性结构的指针 第二个是绑定类型 它有两个取值PTHREAD_SCOPE_SYSTEM绑定的和PTHREAD_SCOPE_PROCESS非绑定的。

另外一个可能常用的属性是线程的优先级它存放在结构sched_param中。用函数pthread_attr_getschedparam和函数pthread_attr_setschedparam进行存放一般说来我们总是先取优先级对取得的值修改后再存放回去。

4线程的数据处理

和进程相比线程的最大优点之一是数据的共享性各个进程共享父进程处沿袭的数据段可以方便的获得、修改数据。但这也给多线程编程带来了许多问题。我们必须当心有多个不同的进程访问相同的变量。许多函数是不可重入的即同

精品资料

时不能运行一个函数的多个拷贝除非使用不同的数据段。在函数中声明的静态变量常常带来问题函数的返回值也会有问题。

互斥锁

互斥锁用来保证一段时间内只有一个线程在执行一段代码。必要性显而易见假设各个线程向同一个文件顺序写入数据最后得到的结果一定是灾难性的。条件变量

互斥锁一个明显的缺点是它只有两种状态锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足它常和互斥锁一起使用。使用时条件变量被用来阻塞一个线程当条件不满足时线程往往解开相应的互斥锁并等待条件发生变化。

信号量

信号量既可以作为二值计数器(即0,1),也可以作为资源计数器.

信号量本质上是一个非负的整数计数器它被用来控制对公共资源的访问。当公共资源增加时调用函数sem_post 增加信号量。只有当信号量值大于时才能使用公共资源使用后函数sem_wait  减少信号量。函数sem_trywait  和函数pthread_mutex_trylock 起同样的作用它是函数sem_wait  的非阻塞版本。

实验内容线程函数编译时需要添加特殊编译选项 gcc *.c-lp th read-o

1 、 完成教材上th read.c的例子想一下每次执行时结果相同吗为什么答每个线程的运行和结束时无序的、独立与并行的。

实验代码

精品资料

/* thread c*/

#include<stdio h>

#include<stdl ib h>

#include<pthread h>

#define THREAD_NUMBER3/*线程数*/

#define REPEAT_NUMBER5/*每个线程中的小任务数*/

#define DELAY_TIME_LEVELS60/*小任务之间的最大时间间隔*/void*thrd_func(void*arg) //指针好乱这里看不懂定义了什么求解释

//定义了一个返回值为指向空类型的指针的函数该函数的参数为一个指针

{ /*线程函数例程*/intthrd_num=(int)arg; //这个是赋值吗看不懂求解释

//定义了一个整型参数取值为arg intdelay_time=0;intcount=0;printf("Thread%d is starting\n", thrd_num);for (count=0;count<REPEAT_NUMBER;count++)

{delay_time=(int)(rand() *DELAY_TIME_LEVELS/(RAND_MAX))+ 1 ;pri ntf("\tThread%d: job%d delay=%d\n",thrd_num,count,delay_ti me);sleep(delay_time); //暂停秒//暂停随机秒

}

//\t输出一个Tab占8列

//输出格式  Thread thrd_num: job countdelay=delay_time 回车pri ntf("Th read%d fin i shed\n", th rd_num);

//输出格式 Thread thrd_num finished 回车pthread_exit(NULL);

}int main(void)

{pthread_t thread[THREAD_NUMBER];

//定义了一个类型为pthread_t的数组数组元素的个数为3intno=0, res;void* thrd_ret; //这句什么意思求解释

//定义了一个指针指向哪里后面的程序里有。srand(time(NULL)); //这句什么意思求解释

//用系统时间计算一个随机数。for (no=0;no<THREAD_NUMBER; no++)

{

/*创建多线程*/res=pthread_create(&thread[no],NULL, thrd_func, (void*)no); //&thread[no]线程标识符//pthread_create函数的参数含义请看书。if (res!=0) //创建线程出错时res=错误码

{printf("Create thread%d fai led\n",no);

精品资料

exit(res);//上面的不是退出进程而是判断pthread_create 函数是否成功执行。

}

}printf("Create treads success\n Waiting for threads to finish \n");

//如果上面没退出进程则创建线程成功for (no=0;no<THREAD_NUMBER; no++)

{

/*等待线程结束*/res=pthread_join(thread[no],&thrd_ret);

// thread[no]线程标识符此例总共有thread[0]  thread[1]  thread[2]  3个线程//请看书上pthread_join  函数的参数含义。if (!res) //res=0时挂起线程成功

//res=0时说明pthread_join  函数执行成功。

{pri ntf("Th read%d j oin ed\n", no);

}else

{pri ntf("Thread%d join fai l ed\n",no);

}

}return 0;

}

2、 完成教材上th read_m utex.c例查看运行情况。和上例比较有何不同想一下为什么会出现这种差异

答这里3个线程之间的运行顺序跟创建线程的顺序相同。

#include<stdio h>

#include<stdlib h>

#include<pthread h>

#define THREAD_NUM 3/*线程数*/

#define REPEAT_NUM 3/*每个线程的小任务数*/

#define DELAY_TIME_LEVELS 60/*小任务之间的最大时间间隔*/pthread_mutex_t mutex;void*thrd_func(void*arg)

{int thrd_num=(int)arg;int delay_time=0,count=0;int res;

/*互斥锁上锁*/

精品资料

res=pthread_mutex_lock(&mutex);if(res)

{printf("Thread%d lock failed\n", thrd_num);pthread_exit(NULL);

}printf("Thread%d is starting\n", thrd_num);for(count=0;count<REPEAT_NUM;count++)

{delay_time=(int)(rand() *DELAY_TIME_LEVELS/(RAND_MAX))+1;sleep(delay_time);printf("\tThread%d: job%d delay=%d\n",thrd_num,count,delay_time);}printf("Thread%d finished\n", thrd_num);pthread_mutex_unlock(&mutex);pthread_exit(NULL);

}int main(void) {pthread_t thread[THREAD_NUM];int no=0, res;void*thrd_ret;srand(time(NULL));

/*互斥锁初始化*/pthread_mutex_init(&mutex,NULL);for (no=0; no<THREAD_NUM;no++)

{res=pthread_create(&thread[no],NULL, thrd_func, (void*)no);if(res !=0)

{printf("Create thread%d failed\n",no);exit(res);

}

}printf("Create treads success\n Waiting for threads tofinish \n");for(no=0;no<THREAD_NUM;no++)

{res=pthread_join(thread[no],&thrd_ret);if(!res)

{printf("Thread%d joined\n",no);

}

精品资料

else

{printf("Thread%d join failed\n",no);

}

}pthread_mutex_destroy(&mutex);return 0;

}

3、 完成教材上th read_attr.c例子并运行查看结果然后和前面两个例子比较查看系统资源的差异。

答理论中线程在运行结束后就回收系统资源并释放内存。

程序代码

#include<stdio h>

#include<stdlib h>

#include<pthread h>

#define REPEAT_NUMBER 3/*线程中的小任务数*/

#define DELAY_TIME_LEVELS 100/*小任务之间的最大时间间隔*/int finish_flag=0;void*thrd_func(void*arg)

{int delay_time=0;int count=0;printf("Thread is starting\n");for (count=0;count<REPEAT_NUMBER;count++)

{delay_time=(int)(rand() *DELAY_TIME_LEVELS/(RAND_MAX))+1;sleep(delay_time);printf("\tThread: job%d delay=%d\n",count,delay_time);

}printf("Thread finished\n");f inish_flag=1;pthread_exit(NULL);

}int main(void)

{pthread_t thread;pthread_attr_t attr;

精品资料

int no=0, res;void*thrd_ret;srand(time(NULL));

/*初始化线程属性对象*/res=pthread_attr_init(&attr);if(res !=0)

{printf("Create attribute failed\n");exit(res);

}

/*设置线程绑定属性*/res=pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);

/*设置线程分离属性*/res+=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACH ED);if(res !=0)

{printf("Setting attribute failed\n");exit(res);

}res=pthread_create(&thread,&attr, thrd_func,NULL);if(res !=0)

{printf("Create thread failed\n");exit(res);

}

/*释放线程属性对象*/pthread_attr_destroy(&attr);printf("Create tread success\n");whi le(!finish_flag)

{printf("Waiting for thread to finish \n");sleep(2);

}return 0;

}

4、 完成教材上多线程实验的实验内容。并分析程序的执行结果。精品资料

实验总结

由运行结果可以看出创建线程、释放资源按照顺序而每个线程的运行和结束是独立与并行的。

精品资料

95IDC香港特价物理机服务器月付299元起,5个ip/BGP+CN2线路;美国CERA服务器仅499元/月起

95idc是一家香港公司,主要产品香港GIA线路沙田CN2线路独服,美国CERA高防服务器,日本CN2直连服务器,即日起,购买香港/日本云主机,在今年3月份,95IDC推出来一款香港物理机/香港多ip站群服务器,BGP+CN2线路终身7折,月付350元起。不过今天,推荐一个价格更美的香港物理机,5个ip,BGP+CN2线路,月付299元起,有需要的,可以关注一下。95idc优惠码:优惠码:596J...

Stablehost 美国主机商黑五虚拟主机四折

如今我们网友可能较多的会选择云服务器、VPS主机,对于虚拟主机的话可能很多人不会选择。但是我们有些外贸业务用途的建站项目还是会有选择虚拟主机的。今天看到的Stablehost 商家虚拟主机在黑五期间也有四折优惠,对于这个服务商而言不是特别的喜欢,虽然他们商家和我们熟悉的老鹰主机商有些类似,且在后来老鹰主机改版和方案后,Stablehost 商家也会跟随改版,但是性价比认为不如老鹰主机。这次黑色星期...

企鹅小屋6折年付240元起,美国CN2 GIA VPS促销,独享CPU,三网回程CN2 GIA

企鹅小屋怎么样?企鹅小屋最近针对自己的美国cn2 gia套餐推出了2个优惠码:月付7折和年付6折,独享CPU,100%性能,三网回程CN2 GIA网络,100Mbps峰值带宽,用完优惠码1G内存套餐是年付240元,线路方面三网回程CN2 GIA。如果新购IP不能正常使用,请在开通时间60分钟内工单VPS技术部门更换正常IP;特价主机不支持退款。点击进入:企鹅小屋官网地址企鹅小屋优惠码:年付6折优惠...

linux多线程编程为你推荐
滴滴软银合资嘀嘀打车是腾讯的还是阿里巴巴的免费送q币活动免费送q币送钻的活动p图软件哪个好用手机p图软件那个好闪迪和金士顿哪个好u盘是金士顿好还是闪迪好?压缩软件哪个好安卓手机哪一款解压缩软件比较好用?谢谢!二手车网站哪个好买二手车去哪里买比较划算?加速器哪个好主流加速器哪个好qq空间登录界面我的手机QQ打开应该是九个选项,什么空间,但是现在打开怎么直接是QQ登录界面,这个撇手机辽宁联通网上营业厅网中国联通的初始服务密码一般是多少电信dns服务器地址电信宽带的DNS服务地址是多少
域名查询系统 七牛优惠码 la域名 godaddy支付宝 申请空间 个人免费空间 vip购优汇 秒杀预告 双线主机 169邮箱 速度云 cdn加速是什么 shuang12 论坛主机 实惠 美国vpn代理 qq空间打开很慢 hosts文件 weblogic部署 美国vpn服务器 更多