pthread_mutex_t
原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和本声明。否则将追究法律责
我并不假定你会使用Linux的线程,所以在这里就简单的介绍一下。如果你之前有过多线程方面的编程经验,完全可以忽略本文的内容,因为它非常的初级。
- #include <pthread.h>
当然,进包含一个头文件是不能搞定线程的,还需要连接libpthread.so这个库,因此在程序连接阶段应该有类似这样的指令:
1. 第一个例子
- int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*) void *arg);
- #include <stdio.h>
- #include <pthread.h>
- void* thread( void *arg )
- {
- printf( "This is a thread and arg = %d.\n", *(int*)arg);
- *(int*)arg = 0;
- return arg;
- }
- int main( int argc, char *argv[] )
- {
- pthread_t th;
- int ret;
- int arg = 10;
- int *thread_ret = NULL;
- ret = pthread_create( &th, NULL, thread, &arg );
- if( ret != 0 ){
- printf( "Create thread error!\n");
- return -1;
- }
- printf( "This is the main process.\n" );
- pthread_join( th, (void**)&thread_ret );
- printf( "thread_ret = %d.\n", *thread_ret );
- return 0;
- }
代码1第一个多线程编程例子
2. 线程的合并与分离
3. 线程的属性
- int pthread_attr_init(pthread_attr_t *attr);
- int pthread_attr_destory(pthread_attr_t *attr);
3.1 绑定属性
- #include <stdio.h>
- #include <pthread.h>
- ……
- int main( int argc, char *argv[] )
- {
- pthread_attr_t attr;
- pthread_t th;
- ……
- pthread_attr_init( &attr );
- pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
- pthread_create( &th, &attr, thread, NULL );
- ……
- }
3.2 分离属性
- pthread_attr_setdetachstat(pthread_attr_t *attr, int detachstate);
它的第二个参数有两个取值:PTHREAD_CREATE_DETACHED(分离的)和PTHREAD_CREATE_JOINABLE(可合并的,也是默认属性)。代码3演示了这个属性的使用。
- #include <stdio.h>
- #include <pthread.h>
- ……
- int main( int argc, char *argv[] )
- {
- pthread_attr_t attr;
- pthread_t th;
- ……
- pthread_attr_init( &attr );
- pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
- pthread_create( &th, &attr, thread, NULL );
- ……
- }
3.3 调度属性
- struct sched_param {
- int sched_priority;
- }
- int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param);
- int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <pthread.h>
- #define THREAD_COUNT 12
- void show_thread_policy( int threadno )
- {
- int policy;
- struct sched_param param;
- pthread_getschedparam( pthread_self(), &policy, ¶m );
- switch( policy ){
- case SCHED_OTHER:
- printf( "SCHED_OTHER %d\n", threadno );
- break;
- case SCHED_RR:
- printf( "SCHDE_RR %d\n", threadno );
- break;
- case SCHED_FIFO:
- printf( "SCHED_FIFO %d\n", threadno );
- break;
- default:
- printf( "UNKNOWN\n");
- }
- }
- void* thread( void *arg )
- {
- int i, j;
- long threadno = (long)arg;
- printf( "thread %d start\n", threadno );
- sleep(1);
- show_thread_policy( threadno );
- for( i = 0; i < 10; ++i ) {
- for( j = 0; j < 100000000; ++j ){}
- printf( "thread %d\n", threadno );
- }
- printf( "thread %d exit\n", threadno );
- return NULL;
- }
- int main( int argc, char *argv[] )
- {
- long i;
- pthread_attr_t attr[THREAD_COUNT];
- pthread_t pth[THREAD_COUNT];
- struct sched_param param;
- for( i = 0; i < THREAD_COUNT; ++i )
- pthread_attr_init( &attr[i] );
- for( i = 0; i < THREAD_COUNT / 2; ++i ) {
- param.sched_priority = 10;
- pthread_attr_setschedpolicy( &attr[i], SCHED_FIFO );
- pthread_attr_setschedparam( &attr[i], ¶m );
- pthread_attr_setinheritsched( &attr[i], PTHREAD_EXPLICIT_SCHED );
- }
- for( i = THREAD_COUNT / 2; i < THREAD_COUNT; ++i ) {
- param.sched_priority = 20;
- pthread_attr_setschedpolicy( &attr[i], SCHED_FIFO );
- pthread_attr_setschedparam( &attr[i], ¶m );
- pthread_attr_setinheritsched( &attr[i], PTHREAD_EXPLICIT_SCHED );
- }
- for( i = 0; i < THREAD_COUNT; ++i )
- pthread_create( &pth[i], &attr[i], thread, (void*)i );
- for( i = 0; i < THREAD_COUNT; ++i )
- pthread_join( pth[i], NULL );
- for( i = 0; i < THREAD_COUNT; ++i )
- pthread_attr_destroy( &attr[i] );
- return 0;
- }
3.4 堆栈大小属性
- int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
3.5 满栈警戒区属性
- int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
4. 线程本地存储
- int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
- int pthread_key_delete(pthread_key_t key);
- void* pthread_getspecific(pthread_key_t key);
- int pthread_setspecific(pthread_key_t key, const void *value);
- #include <stdio.h>
- #include <stdlib.h>
- #include <pthread.h>
- #define THREAD_COUNT 10
- pthread_key_t g_key;
- typedef struct thread_data{
- int thread_no;
- } thread_data_t;
- void show_thread_data()
- {
- thread_data_t *data = pthread_getspecific( g_key );
- printf( "Thread %d \n", data->thread_no );
- }
- void* thread( void *arg )
- {
- thread_data_t *data = (thread_data_t *)arg;
- printf( "Start thread %d\n", data->thread_no );
- pthread_setspecific( g_key, data );
- show_thread_data();
- printf( "Thread %d exit\n", data->thread_no );
- }
- void free_thread_data( void *arg )
- {
- thread_data_t *data = (thread_data_t*)arg;
- printf( "Free thread %d data\n", data->thread_no );
- free( data );
- }
- int main( int argc, char *argv[] )
- {
- int i;
- pthread_t pth[THREAD_COUNT];
- thread_data_t *data = NULL;
- pthread_key_create( &g_key, free_thread_data );
- for( i = 0; i < THREAD_COUNT; ++i ) {
- data = malloc( sizeof( thread_data_t ) );
- data->thread_no = i;
- pthread_create( &pth[i], NULL, thread, data );
- }
- for( i = 0; i < THREAD_COUNT; ++i )
- pthread_join( pth[i], NULL );
- pthread_key_delete( g_key );
- return 0;
- }
5. 线程的同步
5.1 互斥锁
- int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
- int pthread_mutex_destory(pthread_mutex_t *mutex );
- int pthread_mutex_lock(pthread_mutex_t *mutex);
- int pthread_mutex_trylock(pthread_mutex_t *mutex);
- int pthread_mutex_unlock(pthread_mutex_t *mutex);
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <unistd.h>
- #include <pthread.h>
- pthread_mutex_t g_mutex;
- int g_lock_var = 0;
- void* thread1( void *arg )
- {
- int i, ret;
- time_t end_time;
- end_time = time(NULL) + 10;
- while( time(NULL) < end_time ) {
- ret = pthread_mutex_trylock( &g_mutex );
- if( EBUSY == ret ) {
- printf( "thread1: the varible is locked by thread2.\n" );
- } else {
- printf( "thread1: lock the variable!\n" );
- ++g_lock_var;
- pthread_mutex_unlock( &g_mutex );
- }
- sleep(1);
- }
- return NULL;
- }
- void* thread2( void *arg )
- {
- int i;
- time_t end_time;
- end_time = time(NULL) + 10;
- while( time(NULL) < end_time ) {
- pthread_mutex_lock( &g_mutex );
- printf( "thread2: lock the variable!\n" );
- ++g_lock_var;
- sleep(1);
- pthread_mutex_unlock( &g_mutex );
- }
- return NULL;
- }
- int main( int argc, char *argv[] )
- {
- int i;
- pthread_t pth1,pth2;
- pthread_mutex_init( &g_mutex, NULL );
- pthread_create( &pth1, NULL, thread1, NULL );
- pthread_create( &pth2, NULL, thread2, NULL );
- pthread_join( pth1, NULL );
- pthread_join( pth2, NULL );
- pthread_mutex_destroy( &g_mutex );
- printf( "g_lock_var = %d\n", g_lock_var );
- return 0;
- }
5.2 条件变量
- int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
- int pthread_cond_destory(pthread_cond_t *cond);
- int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
- int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, const timespec *abstime);
- int pthread_cond_signal(pthread_cond_t *cond);
- int pthread_cond_broadcast(pthread_cond_t *cond);
- #include <stdio.h>
- #include <stdlib.h>
- #include <pthread.h>
- #define BUFFER_SIZE 5
- pthread_mutex_t g_mutex;
- pthread_cond_t g_cond;
- typedef struct {
- char buf[BUFFER_SIZE];
- int count;
- } buffer_t;
- buffer_t g_share = {"", 0};
- char g_ch = 'A';
- void* producer( void *arg )
- {
- printf( "Producer starting.\n" );
- while( g_ch != 'Z' ) {
- pthread_mutex_lock( &g_mutex );
- if( g_share.count < BUFFER_SIZE ) {
- g_share.buf[g_share.count++] = g_ch++;
- printf( "Prodcuer got char[%c]\n", g_ch - 1 );
- if( BUFFER_SIZE == g_share.count ) {
- printf( "Producer signaling full.\n" );
- pthread_cond_signal( &g_cond );
- }
- }
- pthread_mutex_unlock( &g_mutex );
- }
- printf( "Producer exit.\n" );
- return NULL;
- }
- void* consumer( void *arg )
- {
- int i;
- printf( "Consumer starting.\n" );
- while( g_ch != 'Z' ) {
- pthread_mutex_lock( &g_mutex );
- printf( "Consumer waiting\n" );
- pthread_cond_wait( &g_cond, &g_mutex );
- printf( "Consumer writing buffer\n" );
- for( i = 0; g_share.buf[i] && g_share.count; ++i ) {
- putchar( g_share.buf[i] );
- --g_share.count;
- }
- putchar('\n');
- pthread_mutex_unlock( &g_mutex );
- }
- printf( "Consumer exit.\n" );
- return NULL;
- }
- int main( int argc, char *argv[] )
- {
- pthread_t ppth, cpth;
- pthread_mutex_init( &g_mutex, NULL );
- pthread_cond_init( &g_cond, NULL );
- pthread_create( &cpth, NULL, consumer, NULL );
- pthread_create( &ppth, NULL, producer, NULL );
- pthread_join( ppth, NULL );
- pthread_join( cpth, NULL );
- pthread_mutex_destroy( &g_mutex );
- pthread_cond_destroy( &g_cond );
- return 0;
- }
此外,利用条件变量和互斥锁,可以模拟出很多其它类型的线程同步机制,比如:event、semaphore等。本书不再多讲,有兴趣的读者可以参考其它著作。或自己根据它们的行为自己来模拟实现。
pthread_mutex_t的更多相关文章
- Linux线程-互斥锁pthread_mutex_t
在线程实际运行过程中,我们经常需要多个线程保持同步.这时可以用互斥锁来完成任务:互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthrea ...
- 互斥锁pthread_mutex_t的使用(转载)
1. 互斥锁创建 有两种方法创建互斥锁,静态方式和动态方式.POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,方法如下: pthread_mut ...
- 利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题
首先说一下什么是哲学家进餐问题,这是操作系统课程中一个经典的同步问题, 问题如下:如上图,有6个哲学家和6根筷子(那个蓝色部分表示哲学家,那个紫色长条部分表示筷子),他们分别被编了0~5的号!如果某个 ...
- pthread_mutex_init & 互斥锁pthread_mutex_t的使用
pthread_mutex_init l 头文件: #include <pthread.h> l 函数原型: int pthread_mutex_init( ...
- linuxc_螺纹锁紧pthread_mutex_t
在实际执行过程中的线程,我们经常需要同步多线程. 然后你可以使用互斥锁来完成任务:在使用过程中互斥锁,有pthread_mutex_init,pthread_mutex_destory,pthread ...
- ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程
为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...
- linux中的C里面使用pthread_mutex_t锁(转载)
转自:http://blog.csdn.net/w397090770/article/details/7264315 linux下为了多线程同步,通常用到锁的概念. posix下抽象了一个锁类型的结构 ...
- pthread_mutex_t & pthread_cond_t 总结
pthread_mutex_t & pthread_cond_t 总结 一.多线程并发 1.1 多线程并发引起的问题 我们先来看如下代码: #include <stdio.h> # ...
- Linux 互斥锁的实现原理(pthread_mutex_t)
本文参考--http://www.bitscn.com/os/linux/201608/725217.html 和http://blog.csdn.net/jianchaolv/article/det ...
随机推荐
- HDU ACM 2121 Ice_cream’s world II (无根最小树形图)
[解题思路]这题先看了NotOnlySuccess的解题思路,即设置虚根再处理的做法:弄了一个上午,再次有种赶脚的感觉~~如果需要找出为什么需要去比所有权值之和更大的数为新增的虚边的话,一开始我理解仅 ...
- cocos2dx移植android平台-我的血泪史
版权声明:本文由( 小塔 )原创,转载请保留文章出处! 本文链接:http://www.zaojiahua.com/android-platform.html 本人这几天一直都没有跟新自己的网站内容, ...
- HD2029
Palindromes _easy version Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- Vusual C++连接Mysql和从MySql中取出数据的API介绍
.1 mysql_real_connect() 2.1.1 函数原型: MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const ...
- Umbraco部署到IIS中权限问题(back office没有权限新建template)
在开发项目中,发现把基于Umbraco平台开发的网站部署到服务器的IIS之后,访问该网站的back office 在back office中增加一个template时,发送错误,提示 Access t ...
- django admin site配置(二)
1. ModelAdmin.inlines 将有外键的子类包含进视图 ,实例: class Author(models.Model): name = models.CharField(max_leng ...
- Kafka学习记录
1 Kafka的基本介绍 Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.具有快速.可扩展.分布式.可复制等特点.Kafka与传 ...
- 最小生成树之Prime法
关于最小生成树的概念,在前一篇文章中已经讲到,就不在赘述了.下面介绍Prime算法: 其基本思想为:从一个顶点出发,选择由该顶点出发的最小权值边,并将该边的另一个顶点包含进来,然后找出 ...
- 标准Dispose实现 (转)
需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源 ...
- word2013中取消句首字母自动大写
经常使用word的朋友都知道word中一行的首字母会自动大写,这给用户带来方便的同时,也产生了问题,因为有时候我们并不希望每行开头的首字母大写.要取消首字母自动大写可以取消勾选"首句字母大写 ...