线程linux下C语言多线程编程实例

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

linux下C语言多线程编程实例

2007年11月29日星期四10:39

学东西往往实例才是最让人感兴趣的老是学基础理论不动手感觉没有成就感呵呵。下面先来一个实例。我们通过创建两个线程来实现对一个数的递加。

或许这个实例没有实际运用的价值但是稍微改动一下我们就可以用到其他地方去拉。下面是我们的代码

/*thread_example. c:cmultiplethreadprogramminginlinux

*author:falcon

*E-mai l:tunzhj03@st. lzu.edu. cn

*/

#include<pthread.h>

#include<stdio.h>

#include<sys/time.h>

#include<string.h>

#defineMAX10pthread_tthread[2] ;pthread_mutex_tmut;intnumber=0, i;void*thread1 ()

{printf("thread1 : I'mthread1\n") ;for(i=0; i<MAX; i++)

{pr intf("thread 1 :number=%d\n",number) ;pthre ad_mutex_lock(&mut) ;number++;pthread_mutex_unlock(&mut) ;s l eep(2) ;

}printf("thread1 :主函数在等我完成任务吗 \n") ;pthread_exit(NULL) ;

}void*thread2()

{printf("thread2: I'mthread2\n") ;for(i=0; i<MAX; i++)

{pr intf("thread2:number=%d\n",number) ;pthre ad_mutex_lock(&mut) ;number++;pthread_mutex_unlock(&mut) ;s l eep(3) ;

}printf("thread2:主函数在等我完成任务吗

\n") ;pthread_exit(NULL) ;

}vo i dthread_create(voi d)

{inttemp;memset(&thread,0, sizeof(thread) ) ;//comment1

/*创建线程*/if( (temp=pthread_create(&thread[0],NULL,thread1,NULL) ) !=0)//c omment 2printf("线程1创建失败!\n") ;else printf("线程1被创建\n") ;if( (temp=pthread_create(&thread[1],NULL,thread2,NULL) ) !=0)//c omment 3printf("线程2创建失败") ;else printf("线程2被创建\n") ;

}voidthread_wait(void)

{

/*等待线程结束*/if(thread[0] !=0) {//comment4pthread_join(thread[0],NULL) ;printf("线程1已经结束\n") ;

}if(thread[1] !=0) {//comment5pthread_join(thread[1],NULL) ;printf("线程2已经结束\n") ;

}

}intmain()

{

/*用默认属性初始化互斥锁*/pthread_mutex_init(&mut,NULL) ;printf("我是主函数哦我正在创建线程呵呵

\n") ;thr ead_cr eat e() ;printf("我是主函数哦我正在等待线程完成任务阿 呵呵\n") ;t hr e ad_wa i t() ;return0;

}

下面我们先来编译、执行一下

引文:falcon@falcon:~/program/c/code/ftp$gcc-lpthread-othread_examplethread_example.c falcon@falcon:~/program/c/code/ftp$./thread_example

我是主函数哦我正在创建线程呵呵

线程1被创建

线程2被创建

我是主函数哦我正在等待线程完成任务阿呵呵thread1: I'mthread1thread1:number=0thread2: I'mthread2thread2:number=1thread1:number=2thread2:number=3thread1:number=4thread2:number=5thread1:number=6thread1:number=7thread2:number=8thread1:number=9thread2:number=10thread1:主函数在等我完成任务吗

线程1已经结束thread2:主函数在等我完成任务吗

线程2已经结束

实例代码里头的注释应该比较清楚了吧下面我把网路上介绍上面涉及到的几个函数和变量给引用过来。

引文:

线程相关操作

一pthread_t pthread_t在头文件/usr/include/bits/pthreadtypes.h中定义typedefunsignedlongintpthread_t;

它是一个线程的标识符。

二pthread_create

函数pthread_create用来创建一个线程 它的原型为externintpthread_create__P( (pthread_t*__thread,__constpthread_attr_t*__attr,void*(*__start_routine) (void*),void*__arg) ) ;

第一个参数为指向线程标识符的指针第二个参数用来设置线程属性第三个参数是线程运行函数的起始地址最后一个参数是运行函数的参数。这里我们的函数thread不需要参数所以最后一个参数设为空指针。第二个参数我们也设为空指针这样将生成默认属性的线程。对线程属性的设定和修改我们将在下一节阐述。当创建线程成功时 函数返回0若不为0则说明创建线程失败常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程例如线程数目过多了后者表示第二个参数代表的线程属性值非法。创建线程成功后新创建的线程则运行参数三和参数四确定的函数 原来的线程则继续运行下一行代码。

三pthread_joinpthread_exit

函数pthread_join用来等待一个线程的结束。函数原型为externintpthread_join__P( (pthread_t__th,void**__thread_return) ) ;

第一个参数为被等待的线程标识符第二个参数为一个用户定义的指针它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数调用它的函数将一直等待到被等待的线程结束为止 当函数返回时被等待线程的资源被收回。一个线程的结束有两种途径一种是象我们上面的例子一样 函数结束了调用它的线程也就结束了 另一种方式是通过函数pthread_exit来实现。它的函数原型为externvoidpthread_exit__P( (void*__retval) )__attribute__((__noreturn__) ) ; 唯一的参数是函数的返回代码只要pthread_join中的第二个参数thread_return不是NULL这个值将被传递给thread_return。最后要说明的是一个线程不能被多个线程等待否则第一个接收到信号的线程成功返回其余调用pthread_join的线程则返回错误代码ESRCH。

在这一节里我们编写了一个最简单的线程并掌握了最常用的三个函数pthread_createpthread_join和pthread_exit。下面我们来了解线程的一些常用属性以及

如何设置这些属性。

互斥锁相关

互斥锁用来保证一段时间内只有一个线程在执行一段代码。

一pthread_mutex_init

函数pthread_mutex_init用来生成一个互斥锁。 NULL参数表明使用默认属性。如果需要声明特定属性的互斥锁须调用函数pthread_mutexattr_init。 函数pthread_mutexattr_setpshared和函数pthread_mutexattr_settype用来设置互斥锁属性。前一个函数设置属性pshared它有两个取值 P T HR E AD_PR O CE S S_P R I V AT E和P TH RE A D_P RO C ES S_S HAR ED。前者用来不同进程中的线程同步后者用于同步本进程的不同线程。在上面的例子中我们使用的是默认属性

PTHREAD_PROCES S_PR IVATE。后者用来设置互斥锁类型可选的类型有PTHREAD_MUTEX_NORMAL、P THREAD_MUTE X_ERRORCHE CK、 PTHREAD_MUTEX_RE CUR S I VE和P THREAD_MUT EX_D EFAULT。它们分别定义了不同的上所、解锁机制一般情况下选用最后一个默认属性。

二pthread_mutex_lockpthread_mutex_unlockpthread_delay_np pthread_mutex_lock声明开始用互斥锁上锁此后的代码直至调用pthread_mutex_unlock为止均被上锁 即同一时间只能被一个线程调用执行。 当一个线程执行到pthread_mutex_lock处时如果该锁此时被另一个线程使用那此线程被阻塞 即程序将等待到另一个线程释放此互斥锁。

注意

1需要说明的是上面的两处sleep不光是为了演示的需要也是为了让线程睡眠一段时间让线程释放互斥锁等待另一个线程使用此锁。下面的参考资料1里头说明了该问题。但是在linux 下好像没有pthread_delay_np那个函数我试了一下提示没有定义该函数的引用 所以我用了sleep来代替不过参考资料2中给出另一种方法好像是通过pthread_cond_timedwait来代替里头给出了一种实现的办法。

2请千万要注意里头的注释comment1-5那是我花了几个小时才找出的问题所在。

如果没有comment1和comment4,comment5,将导致在pthread_join的时候出现段错误另外上面的comment2和comment3是根源所在所以千万要记得写全代码。因为上面的线程可能没有创建成功导致下面不可能等到那个线程结束而在用pthread_join的时候出现段错误访问了未知的内存区 。另外在使用memset的时候需要包含string.h头文件哦

参考资料

1。 Linux下的多线程编程

2。 pthread_delay_np 这里头有个关于pos ix条件变量的例子

3。 pthread_join和段错误非常感谢这里头的哥们千万要看哦

4。 posix线程编程指南学习 linux下多线程不看这个你会后悔的http://www. l inuxforum.net/forum/showf lat.php?Cat=&Board=program&Numbe r=294073&page=0&view=collapsed&sb=5&o=7&fpart=http://www.bczs.net/xml /2005/11/5/4374188.xmlhttp://bbs. chinaunix.net/archiver/?tid-

584593.htmlhttp://linux. chinaunix.net/doc/program/2001-08-

11/642. shtml

提速啦(24元/月)河南BGP云服务器活动 买一年送一年4核 4G 5M

提速啦的来历提速啦是 网站 本着“良心 便宜 稳定”的初衷 为小白用户避免被坑 由赣州王成璟网络科技有限公司旗下赣州提速啦网络科技有限公司运营 投资1000万人民币 在美国Cera 香港CTG 香港Cera 国内 杭州 宿迁 浙江 赣州 南昌 大连 辽宁 扬州 等地区建立数据中心 正规持有IDC ISP CDN 云牌照 公司。公司购买产品支持3天内退款 超过3天步退款政策。提速啦的市场定位提速啦主...

捷锐数据399/年、60元/季 ,香港CN2云服务器 4H4G10M

捷锐数据官网商家介绍捷锐数据怎么样?捷锐数据好不好?捷锐数据是成立于2018年一家国人IDC商家,早期其主营虚拟主机CDN,现在主要有香港云服、国内物理机、腾讯轻量云代理、阿里轻量云代理,自营香港为CN2+BGP线路,采用KVM虚拟化而且单IP提供10G流量清洗并且免费配备天机盾可达到屏蔽UDP以及无视CC效果。这次捷锐数据给大家带来的活动是香港云促销,总共放量40台点击进入捷锐数据官网优惠活动内...

NameSilo域名优惠码活动

NameSilo是通过之前的感恩节优惠活动中认识到这家注册商的,于是今天早上花了点时间专门了解了NameSilo优惠码和商家的详细信息。该商家只销售域名,他们家的域名销售价格还是中规中矩的,没有像godaddy域名标价和使用优惠之后的价格悬殊很大,而且其特色就是该域名平台提供免费的域名停放、免费隐私保护等功能。namesilo新注册域名价格列表,NameSilo官方网站:www.namesilo....

linux多线程编程为你推荐
日本软银集团请介绍一下日本软银。向那些中国企业投资过?2017爱奇艺vip免费领取求免费的爱奇艺会员???天玑1000plus和骁龙865哪个好各位觉得联发科最新芯片天机1000靠谱吗?真的能打过麒麟990?浏览器哪个好目前什么浏览器最好用?集成显卡和独立显卡哪个好独立显卡和集成显卡哪个更好些ps软件哪个好什么PS软件好无纺布和熔喷布口罩哪个好活性碳口罩和无纺布口罩有什么不同?雅思和托福哪个好考现在考雅思还是托福好雅思和托福哪个好考托福好考还是雅思好考?qq空间登录不了登陆不了QQ空间
台湾虚拟主机 中国万网域名注册 vps租用 域名停靠一青草视频 idc评测 burstnet 韩国空间 mach 网站保姆 淘宝双十一2018 服务器怎么绑定域名 dropbox网盘 国内加速器 台湾谷歌地址 坐公交投2700元 域名转向 me空间社区 腾讯实名认证中心 t云 爱奇艺会员免费试用 更多