线程调用

线程创建。
  –在进程中只有一个控制线程
  –程序开始运行的时候每个进程只有一个线程,它是以单线程方式启动的,在创建多个线程以前,进程的行为与传统的进程没有区别。
  –gcc在链接的时候需要增加-lpthread选项。
  –创建一个线程调用pthread_create函数。

#include <pthread.h>

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

如果pthread_create成功返回,由thread指向的内存单元被设置为新创建线程的线程ID。
attr参数用于定制各种不同的线程属性。
新创建的线程从start_rtn函数地址开始执行,该函数只有一个void *参数,如果需要向start_rtn函数传递多个参数,就需要把这些参数放到一个结构中,然后把这个结构的地址做为void *传入。
线程创建的时候不能保证哪个先运行。
pthread函数调用失败,返回errno
  –注意:每个线程都拥有一份errno副本,不同的线程拥有不同的errno
 
 
 
pthread_create例子
gcc链接时需要加-lpthread选项
void *func(void *arg)
{
    printf("pthread start
");
    return NULL;
}
int main(int arg, char * args[])
{
    pthread_t thr_d;
    int err = pthread_create(&thr_d, NULL, func, NULL);
    if (err != 0)
    {
        printf("create pthread failed
");
    }
    else
    {
        printf("create pthread success
");
    }
    sleep(1);
    return 0;
}
线程终止。
  –任一线程调用了exit函数,整个进程就会终止。
  –如果信号默认动作是终止进程,那么信号发送到该线程,整个进程也会被终止。
单个线程通过以下三种方式退出
  –线程只是从启动函数中返回,返回值是线程的退出码。
  –线程可以被同一进程中的其他线程取消。
  –线程调用pthread_exit。

void pthread_exit(void *arg);

arg是个无类型指针,该指针会被其他线程调用pthread_join捕捉。

pthread_exit例子
void *func(void *arg)
{
    printf("pthread start
");
    static int i = 1;
    pthread_exit(&i);
}
int main(int arg, char * args[])
{
    pthread_t thr_d;
    pthread_create(&thr_d, NULL, func, NULL);
    sleep(1);
    return 0;
}
int pthread_join(pthread_t th, void **thr_return);。
pthread_join函数用于挂起当前线程,直至th指定的线程终止为止。
如果另一个线程返回值不是NULL,则保存在thr_return地址中。
一个线程所使用的内存资源在应用pthread_join调用之前不会被重新分配,所以对于每个线程必须调用一次pthread_join函数。
其他线程不能对同一线程再应用pthread_join调用。
 
 
pthread_join例子
void *func(void *arg)
{
    printf("pthread start
");
    static int i = 0;
    sleep(2);
    pthread_exit(&i);
}
int main(int arg, char * args[])
{
    pthread_t thr_d;
    pthread_create(&thr_d, NULL, func, NULL);
    void *p;
    pthread_join(thr_d, &p);
    int *pi = (int *)p;
    printf("thread exit %d
", *pi);
    return 0;
}
int pthread_detach(pthread_t th);
pthread_detach函数使线程处于被分离状态。
对于被分离状态的线程,不需要调用pthread_join,如果其他线程调用pthread_join失败,返回EINVAL。
如果不等待一个线程,同时对线程的返回值不感兴趣,可以设置这个线程为被分离状态,让系统在线程退出的时候自动回收它所占用的资源。
一个线程不能自己调用pthread_detach改变自己为被分离状态,只能由其他线程调用pthread_detach。
 
 
pthread_detach例子
void *func(void *arg)
{
    printf("pthread start
");
    pthread_exit(NULL);
}
int main(int arg, char * args[])
{
    pthread_t thr_d;
    pthread_create(&thr_d, NULL, func, NULL);
    pthread_detach(thr_d);
    sleep(1);
    return 0;
}
int pthread_cancel(pthread_t th);
pthread_cancel函数允许一个线程取消th指定的另一个线程。
函数成功,返回0,否则返回非0。
 
pthread_cancel例子
void *func(void *arg)
{
    printf("pthread start
");
    while(1)
    {
        printf("thread is running
");
        sleep(1);
    }
    pthread_exit(NULL);
}
int main(int arg, char * args[])
{
    pthread_t thr_d;
    pthread_create(&thr_d, NULL, func, NULL);
    pthread_detach(thr_d);
    sleep(6);
    pthread_cancel(thr_d);
    sleep(6);
    printf("end
");
    return 0;
}
int pthread_equal(pthread_t th1,pthread_t th2);
pthread_equal函数比较th1与th2是否为同一个线程,由于不可以将pthread数据类型认为是整数,所以也不能用比较整数的方式比较pthread_t。
如果th1与th2相同,函数返回非0值,如果不同函数返回0。
线程属性
  –以前调用pthread_create传入的attr参数都是空指针,而不是指向pthread_attr_t结构的指针。
  –可以使用pthread_attr_t结构修改线程默认属性,并把这些属性与创建的线程联系起来
  –可以使用pthread_attr_init函数初始化pthread_attr_t结构。
  –调用pthread_attr_init以后,pthread_arrt_t的结构所包含的内容就是操作系统实现支持线程所有属性的默认值。如果要修改其中个别属性的值,需要调用其他函数。

int pthread_attr_destroy(pthread_attr_t *attr);

int pthread_attr_init(pthread_attr_t *attr);

函数pthread_attr_init初始化attr结构。
函数pthread_attr_destroy释放attr内存空间。
pthread_attr_t的结构对于应用程序来讲是不透明的,应用程序不需要了解有关结构的内部组成。
以前介绍了pthread_detach函数的概念,可以通过pthread_attr_t在创建线程的时候就指定线程属性为detach,而不用创建以后再去修改线程属性。
 
 
 

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); 。

函数pthread_attr_setdetachstate把线程属性设置为下面两个合法值之一

说明

PTHREAD_CREATE_DETACHED

设置线程为分离状态

PTHREAD_CREATE_JOINABLE

设置线程为正常状态

pthread_setdetachstate例子
void *func(void *arg)
{
    printf("pthread start
");
    while(1)
    {
        printf("thread is running
");
        sleep(1);
    }
    pthread_exit(NULL);
}
int main(int arg, char * args[])
{
    pthread_t thr_d;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_create(&thr_d, &attr, func, NULL);
    pthread_attr_destroy(&attr);
    sleep(2);
    printf("end
");
    return 0;
}
 
原文地址:https://www.cnblogs.com/shichuan/p/4496160.html