pthread学习

##########################################################################################################

    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, &param);
    
    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;

 fd=open("/dev/xxx", O_RDWR, 0);
 attr=mmap(0, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 close(fd);

*/


#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 );

pthread_once_t once_control = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t* once_control, void (*init_routine)(void));
对于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












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值