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 ...
随机推荐
- 消息队列与RabbitMQ
1 什么是消息队列 消息指进程或应用间通信的数据:队列是保存数据的结构:消息队列是指进程或应用间通信时,保存消息的容器.消息队列独特的机制和结构保证了消息发送者和接收者之间良好的异步通信. 2 为什么 ...
- sql-labs 分享
前段时间在网上发现了一个阿三同学托管在github上的sql注入入门科普项目,感觉挺不错,在此分享一下.虽然现在有很多工具比如sqlmap可以实现自动化的sql注入,但是个人感觉如果只知其然而不知其所 ...
- 自己封装的Socket组件,实现服务端多进程共享Socket对象,协同处理客户端请求
DotNet.Net.MySocket是SLB.NET(Server Load Balance服务器负载均衡)项目中的核心组件. 在实际的项目中发现,单进程的服务端处理高并发的客户请求能力有限. 所以 ...
- flex中文说明手册
http://help.adobe.com/zh_CN/Flex/4.0/UsingFlashBuilder/WS6f97d7caa66ef6eb1e63e3d11b6c4d0d21-7f07.htm ...
- 轻松学习Linux之理解Shell的硬链接与软连接
大家在学习linux的过程中常常遇到一些模糊且容易混淆的概念比如什么是硬链接和软链接,他们有什么区别? 软连接有点象windows中的快捷方式,连接和目标文件具有相同的节点,而硬连接就好象重新复制 ...
- LeetCode104: Maximum Depth of Binary Tree
Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...
- 让MySQL支持中文
这两天在学习webpy,把webpy的一个blog例子扒下来学习一下,默认创建的table当存入中文的时候是乱码,研究了一下这个问题. 1,创建table的时候就使用utf8编码 举个例子: crea ...
- js关闭当前页面(窗口)的几种方式总结
1. 不带任何提示关闭窗口的js代码 <a href="javascript:window.opener=null;window.open('','_self');window.clo ...
- django admin site (三)
1.自定义模板设置: ModelAdmin. add_form_template Path to a custom template, used by add_view(). ModelAdmin. ...
- Jquery 校验文本框只能输入负数、小数、整数
/* umlzhang date:2013-09-12 */ //检验只能输入整数,小数和负数 $(function () { var obj = $(&q ...