##########################################################################################################
pthread_attr_t thread_attr;
struct sched_param param;
pthread_attr_init(&thread_attr);//int pthread_attr_destroy(pthread_attr_t *attr);来销毁,但这里不是指针,在程序结束自动销毁
pthread_attr_setstacksize(&thread_attr, 1024);//配置栈大小
pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO);//策略为FIFO,在rr和fifo策略可以配置下面的优先级
param.sched_priority = 55;//值越大优先级越大.
/*下面函数可以线程可用优先级范围
int sched_get_priority_max(int policy); int sched_get_priority_min(int policy); */
(void)pthread_attr_setschedparam(&thread_attr, ¶m);
hal_device = _hal_device;
pthread_create(&thread_ctx, &thread_attr, &runThread, this);
##########################################################################################################
创建一个进程:
int threadfg = -1;
void start_anim()
{
char a[4]="1234";
if (threadfg == (pthread_t)-1) {//强制转换,不要立即错了
if (pthread_create(&threadfg, NULL, myThreadFun, (void*)a)) {//创建线程,函数为myThreadFun,线程描述符threadfg,参数a。操作成功返回0,失败为其他
threadfg = -1;
printf("Create animation_thread ERROR!!\n");
};
}
}
void myThreadFun(int k)
{
//while(1){}
printf("%d\n",k);
}
void stop_anim()
{
if(threadfg != (pthread_t)-1) {
pthread_cancel(threadfg);//发终止信号
pthread_join(threadfg, NULL);//等待线程结束并回收空间(因此退出线程必须用他),关闭线程。正常退出应该是:将线程的while(x)的x改为false,然后pthread_join等待。如果线程出现阻塞这种方法就不好使了。
//pthread_cancel(threadfg);//=pthread_cancel+pthread_join
threadfg = -1;
}
//do some clean oporation
}
线程是否还活着:int pthread_kill(pthread_t thread, int sig)
返回值:
线程仍然活着:0
线程已不存在:ESRCH
信号不合法:EINVAL
线程锁:
pthread_mutex_t my_mutex; // 定义
初始化:
pthread_mutex_init(&my_mutex, NULL);
使用:
pthread_mutex_lock(&my_mutex);
...//作动作,注意:最好不要用其他锁。
//其实我们很少看到用pthread_mutex_trylock是因为我们锁占用事件尽量短。
pthread_mutex_trylock( &my_mutex )//不等待获取锁,如果返回0,得到锁,如果返回其他都是没获取,看errno。返回0才解锁,否则不用。
pthread_mutex_unlock(&my_mutex);
#################################################################################################
以下代码来自directfb1.6.3,主函数direct_thread_create。
#################################################################################################
mutex.c对锁的处理:
DirectResult
direct_recursive_mutex_init( DirectMutex *mutex )
{
DirectResult ret = DR_OK;
int result;
pthread_mutexattr_t attr;//为互斥锁添加属性
pthread_mutexattr_init( &attr );//锁属性就是初始化,然后创建锁时使用,然后释放,他只是一个辅助
#if HAVE_DECL_PTHREAD_MUTEX_RECURSIVE
/*
http://blog.csdn.net/kingmax26/article/details/5338065
http://linux.die.net/man/3/pthread_mutexattr_settype
PTHREAD_MUTEX_NORMAL;//锁属性有:同线程不能重复上锁(导致死锁),不能解已经解锁的;不能解其他线程锁。如果操作可能会导致代码出错
PTHREAD_MUTEX_ERRORCHECK;//同线程不能重复上锁,不能解已经解锁的锁;不能解其他线程锁。如果操作返回错误代码,看errno。
PTHREAD_MUTEX_RECURSIVE;//可以重复上锁,但要通数量解锁,不能解已经解锁的锁;不能解其他线程锁。如果操作返回错误代码,看errno,需要设置默认PTHREAD_PROCESS_PRIVATE
PTHREAD_MUTEX_DEFAULT。//同线程不能重复上锁(不可预料),不能解已经解锁的;不能解其他线程锁。如果操作可能会导致代码出错.默认PTHREAD_MUTEX_DEFAULT。
*/
pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );//设置锁的属性
//extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict __attr, int *__restrict __kind)获得锁属性
/*扩展,共享属性。为什么很少用,每个进程处理各自独立任务。但是比如服务器高并发的情况,可能服务器会开10个进程同时监听同一端口,这个时候可能会用到。
注:信号量也能做进程间互斥操作的。
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);//设置锁的共享属性。默认PTHREAD_PROCESS_PRIVATE本进程可用
用进程间共享的话,可以使用mmap来配置锁的共享内存:
pthread_mutex_t *attr;
*/
#endif
result = pthread_mutex_init( &mutex->lock, &attr );//第二个参数是锁的属性
//pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;全局锁变量可以静态初始化。
if (result) {
ret = errno2result( errno );
D_PERROR( "Direct/Mutex: Could not initialize recursive mutex!\n" );
}
pthread_mutexattr_destroy( &attr );//释放属性
return (DirectResult) ret;
}
2.条件变量
waitqueue.h
条件变量也可以实现多进程共享,初始化时方法和差不多。
初始化:
pthread_mutex_init(&mmutex, NULL);
pthread_cond_init(&mcond, NULL);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_cond_t mcond = PTHREAD_COND_INITIALIZER;//初始化条件变量
等待条件,和锁一起用:
pthread_mutex_lock(&mmutex);
/*
在进入pthread_cond_wait前锁mmutex会unlock,完成pthread_cond_wait时mmutex会重新lock上。
pthread_cond_timedwait()用于超时等待。
*/
c = pthread_cond_wait(&mcond, &mmutex);
pthread_mutex_unlock(&mmutex);
if (c) {
c = -1;
}
唤醒条件,和锁一起用:
pthread_mutex_lock(&mmutex);
c = pthread_cond_signal(&mcond);//pthread_cond_broadcast( &mcond)用于唤醒所有的pthread_cond_wait(&mcond, &mmutex)等待
pthread_mutex_unlock(&mmutex);
if (c) {
c = -1;
}
释放条件:
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&mcond);
3.线程创建时也是有参数的:
参考thread.c中的direct_thread_init
查看和设置:栈位置和大小,优先级,调度策略,是否和pthread_join同步
http://blog.csdn.net/scanery/article/details/7242768
pthread_attr_setstacksize
pthread_attr_getstacksize
pthread_attr_setdetachstate//设置PTHREAD_CANCEL_ENABLE(支持pthread_cancel,默认),PTHREAD_CREATE_JOINABLE(支持join,默认)
4.一次初始化,也在direct_thread_init函数里面:direct_once( &thread_init_once, init_once );
对于once_control只会做一次init_routine操作。
5.pthread_key_t,用来做线程间共享的内存的
static pthread_key_t thread_key;
pthread_key_create( &thread_key, NULL );//创建key,第二个参数是destructor退出线程回收内存用的,明显多个线程这个创建一次就可以了,就可以用上面的pthread_once
pthread_setspecific( thread_key, thread );//放一个共享数据到thread_key。
thread = pthread_getspecific( thread_key );//从thread_key获取共享数据,thread是void类型。
如:
direct_once( &thread_init_once, init_once );
static void
init_once( void )
{
/* Create the key for the TSD (thread specific data). */
pthread_key_create( &thread_key, NULL );
}
6, D_ASSERT( !pthread_equal( thread->handle.thread, pthread_self() ) );
pthread_self()获得pthread_t线程号,pthread_equal用来比较两个pthread_t是否相等的,多个线程调同一个函数的时候,可以通过他来区分。
pthread_equal返回0表示不等。
7. pthread_detach( threadid );将一个线程分离,就是在调用pthread_join的时候,无需等待,自动释放资源。
pthread_attr_setdetachstate(); PTHREAD_CREATE_DETACHED参数应该是一样的。
8.
void pthread_cleanup_push(void (*routine) (void *), void *arg) void pthread_cleanup_pop(int execute)
pthread_cleanup_push入栈一个函数routine,参数是arg。在线程结束或者pthread_cleanup_pop时调用。主要用于cancel(异常退出)时释放空间pthread_cleanup_pop(1)执行出栈1次,函数是routine