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 ...
随机推荐
- C++11 之 " = delete "
1 缺省函数 设计一个类,没有成员函数 (member function),只有成员数据 (member data) class DataOnly { private: std::string st ...
- Hadoop2.2 federnation联盟的搭建
联盟实际上是一个单独的集群,集群里面包含很多的NameService共享同样的DataNode,同一份数据只上传一份,block块相同,一个集群中删除,另一个集群中还是存在的.同一份数据只是在name ...
- ajax 留言板
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 关于javascript里面仿python切片操作数组的使用方法
其实在使用了好一段时间的 python之后,我觉得最让我念念不忘的并不是python每次在写函数或者循环的时候可以少用{}括号这样的东西(ps:其实也是了..感觉很清爽,而且又开始写js的时候老是想用 ...
- cocos2d-x使用python创建vs模板
cocos2d-x 2.2推荐使用create_project.py创建工程,所有的平台都可以通过这个python文件创建工程.这个文件位置在源码cocos2d-x-2.2.2\tools\proje ...
- delphi 集合
DELPHI没有JAVA的丰富的集合(SET MAP LIST),只有Tlist,可包装各种类型
- Ubuntu安装Burg
友情提示:本文只介绍了如何安装Burg,没有关于卸载Burg的相关说明.事实上,我后来直接新装了12.04,我没有卸载Burg的经验.考虑到Burg事关系统引导的大事,安装的话按本文来做应该没有问题, ...
- datareader几种用法总结
1.本人常用: if (reader["字段名"] != DBNull.Value) { userRegisterInfo.OrgCode = reader["字段名&q ...
- oracle学习 二(持续更新中)
oracle数据库的启动停止 以oracle用户身份登录 登录后输入以下命令: oracle-> sqlplus /nolog SQL*Plus: Release 9.2.0.1.0 - Pro ...
- 经典CSS实现三角形图标原理解析
前言: 在写这篇文章之前,我也看过很多前端大神写的代码,But,都只是粘贴代码和给出显示效果,对于初学者来说大家都喜欢刨根问底,为什么要这样做呢? 接下来就让我给大家分享一下我对CSS实现三角形的理解 ...