POSIX线程的创建和取消(2)

int pthread_create(pthread_t * thread,                      const pthread_attr_t * attr,                      void* (*start_routine)(void*),                      void *arg);  


 pthread_create 的第二个参数pthread_attr_t

struct pthread_attr_t
    {
        enum    新线程是否与进程中其它线程脱离同步
        {
            PTHREAD_CREATE_JOINABLE    [default]   可以在创建后用 pthread_detach 脱离同步
            PTHREAD_CREATE_DETACHED                  不能用 pthread_join 来同步,退出时自行释放资源
        } __detachstate;
    
        enum    新线程的调用策略
        {
            SCHED_OTHER [default]    非实时
            SCHED_RR                           实时,轮转法    - 仅对超级用户有效
            SCHED_FIFO                        实时,先入先出    - 仅对超级用户有效
        } __schedpolicy;
    
        struct sched_param        在运行时用 pthread_setschedparam 更新。
        {
            int sched_priority    线程的运行优先级。当上面的 __schedpolicy 为“实时”时才有效。缺省是零。
        } __schedparam;
    
        enum
        {
            PTHREAD_EXPLICIT_SCHED [default]    显式指定调度策略和调度参数,即使用 attr 中的值
            PTHREAD_INHERIT_SCHED                     继承调用者线程的值
        } __inheritsched;
    
        enum    线程间竞争CPU的范围
        {
            PTHREAD_SCOPE_SYSTEM [default]   目前Linux只实现了这一种
            PTHREAD_SCOPE_PROCESS              仅与同进程的线程竞争
        } __scope;
    }

    下面三个没用过
    * guard size
    * stack address (See unistd.h and bits/posix_opt.h _POSIX_THREAD_ATTR_STACKADDR)
    * stack size (default minimum PTHREAD_STACK_SIZE set in pthread.h)

 创建线程时,如果写成下面的样子,也是可以的。这属于精简模式,作为函数指针的传入参数是和上面等价的:iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);

 等待其它线程停止int pthread_join(pthread_t th, void **thread_return);
    * th - 调用线程变为挂起状态,等待线程退出。退出线程可用 pthread_exit() 或者 cancel 类线程函数。
    * thread_return - 不置为NULL的话,可以传出返回值。

 退出当前线程void pthread_exit(void *retval);
若要在退出时返回数据在retval指向的内存里,务必保证该内存不是在线程局部空间里,否则会随着线程退出而消失。

 可以通过向某线程发送cancel请求而强制终止该线程。该线程置自己为"cancel"状态后,运行至取消点(cancelation point),才会退出。
POSIX标准规定的取消点:
- pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()
- read、write等会引起阻塞的系统调用

但pthread_cancel的手册页声称,由于LinuxThread库与C库结合得不好,因而目前C库函数都不是取消点。
不过,cancel信号会使线程从阻塞的系统调用中退出,并置EINTR错误码。所以可以把这样的系统调用作为取消点:

pthread_testcancel();
retcode = read(fd, buffer, length);
pthread_testcancel();

这样,可达到POSIX的要求。

与取消线程相关的函数
- int pthread_cancel (pthread_t th)    发送取消信号给线程。若成功返回零;失败则非零。发送成功并不意味着线程会终止。

- int pthread_setcancelstate (int state, int *oldstate)    设置本线程对cancel信号的反应。
enum
{
    PTHREAD_CANCEL_ENABLE [default]   收到信号后置自己为取消状态
    PTHREAD_CANCEL_DISABLE                 忽略cancel信号,继续运行
} state

- int pthread_setcanceltype (int type int *oldtype)
enum
{
    PTHREAD_CANCEL_DEFERRED [default]        收到cancel信号后继续运行,到达取消点时退出
    PTHREAD_CANCEL_ASYNCHRONOUS           立即退出
} type    当上面的state为 PTHREAD_CANCEL_ENABLE 时该变量才有效。

- void pthread_testcancel (void)

检查本线程是否处于取消状态,若是,立刻退出。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwwxsz.html