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 ...
随机推荐
- Linux进程间通信——使用共享内存
一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...
- [cocos2d-js]chipmunk例子(二)
; ; ; ; <<; var NOT_GRABABLE_MASK = ~GRABABLE_MASK_BIT; var MainLayer = cc.Layer.extend({ _bal ...
- html5 canvas图片马赛克
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Servlet 2.4 规范之第一篇:概览
写在前面的话: 本系列是对<Java Servlet Specification Version 2.4>的完全翻译,力争但不保证完美表达出英文原文的思想内涵.如有疏漏之处,还 ...
- Qt Creator无法用“UTF-8”编码解码
在Qt Creator 里打开其他编辑器的代码时有时会提示: 无法用"UTF-8"编码解码 在文件上右键使用NotePad++编辑器打开: 选择->格式-&g ...
- LIS (最长上升子序列)
LIS两种写法 O(n^2) dp[i]表示以a[i]结尾的为LIS长度 #include <algorithm> #include <iostream> #include & ...
- 80X86保护模式及其编程(一)
80x86系统寄存器和系统指令 1.标志寄存器(EFLAGS) 标志寄存器EFLAGS的标志位含义如下图: TF 位8是跟踪标志(Trace flag),当设置该位时可为调试操作启动单步执行方式.复位 ...
- SCCM2007
Active Directory系统组发现:此方法按照上次运行发现方法时 Active Directory 中的响应返回对象,可发现活动目录OU.全局组.通用组.嵌套组.非安全组. Active Di ...
- C++字节对齐问题
关于C++字节对齐问题 关于C/C++的字节对齐 这两天写解析SWF文件的程序,在结构体指针和从文件里读出来的进行转换的时候遇到一些问题,就是有一个struct A,比如: struct A { ch ...
- 博客中最快捷的公式显示方式:Mathjax + Lyx
经常为在博客园中显示公式而烦恼的同志们看过来!! 什么是mathjax? 答:就是在web中显示公式用的,基于JavaScript写的,关键是开源,网址http://www.mathjax.org/, ...