Linux C 线程操作

一、线程的基本概念

  1、进程可以分为线程集合和资源集合,线程是一个动态控制对象,它标识进程中的一个控制点,并且执行一系列的指令。资源包含地址空间、打开文件、用户凭证和配额。每个线程有自己的程序计数堆栈和寄存器的值

 2.分类:用户态线程:管理上不需要内核参与,统一由用户程序切换

         缺点:进程中的一个线程容易占用一个时间片,导致其他线程无法运行

     内核态线程:由内核管理,在每个时间片内,内核负责调度进程内线程,一个线程不会独占CPU

                     缺点:有内核态和用户态的切换,速度变慢,随着CPU数量增多,应用程序运行速度加快

  3.线程具有一个ID,一个堆栈,一个执行优先权,以及执行开始的地址

二。创建和结束线程

  1.#include<pthread.h>

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

    pthread_create(&thread1,NULL,(void *)(&print_message),(void*)msg1);

    与创建它的线程同步执行;

    start_routine  线程执行函数

   arg    函数参数

  attr 线程属性 可以为NULL 默认属性

 结束:pthread_exit 或者随着函数结束而结束

 成功返回0,将线程标识符存入指针thread指向的地址;失败返回非0

2.获取线程ID

 pthread_t pthread_self();

printf("Thread ID:%lx ",pthread_self());

3.结束线程

void pthread_exit(void *retval); 将返回一个值到retval

pthread_exit(&retval);

调用成功返回0,失败返回-1

 

编译:gcc -lpthread -o ex7-1 ex7-1.c

4.挂起线程

int pthread_join(pthread_t th,void ** thread_return);挂起当前线程直至线程终止

thread_return 存放其他进程返回值,每个可连接的进程都会执行一次

成功返回0,将th值保存于thread_return,失败返回非0

pthread_create(&thread1,NULL,(void *)(&print_message),(void*)msg1);
pthread_create(&thread2,NULL,(void *)(&print_message),(void*)msg2);

pthread_join(thread1,&retval);//保证两个进程结束以后退出
pthread_join(thread2,&retval);

5.线程同步

1)互斥锁 :原子性 唯一性 非繁忙等待 一个线程已经锁定互斥锁,另一个线程执行锁操作会被挂起,直至锁打开

操作:int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr *attr)

attr 属性,NULL为默认属性

成功返回0,将创建的锁ID放到mutex中

   int pthread_mutex_destroy(pthread_mutex_t *mutex) ;成功返回0,执行失败返回错误编号

  int pthread_mutex_lock(pthread_mutex_t *mutex),锁定指定锁,若已被锁定,阻塞调用线程,当函数返回时说明互斥锁已经成功加锁

  成功返回0,其他值发生错误

 int pthread_mutex_trylock(pthread_mutex_t *mutex),锁定指定锁,若已被锁定,返回错误

成功返回0,失败返回错误

int pthread_mutex_unlock(pthread_mutex_t *mutex), 解锁 成功返回0,其他值以为错误

例。

/*ex7-3*/
#include<stddef.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

#define FALSE 0
#define TRUE 1

void readfun();
void writefun();


char buffer[256];
int buffer_has_item=0;
int retflag=FALSE;
pthread_mutex_t mutex;

int main()
{
pthread_t reader;
pthread_mutex_init(&mutex,NULL);
pthread_create(&reader,NULL,(void *)readfun,NULL);
writefun();
}

void readfun()
{
while(1)
{
if(retflag)
return;
pthread_mutex_lock(&mutex);
if(buffer_has_item==1)
{
printf("%s",buffer);
buffer_has_item=0;
}
pthread_mutex_unlock(&mutex);
}

}

void writefun()
{
int i=0;
while(1)
{
if(i==10)
{
retflag=TRUE;
return;
}
pthread_mutex_lock(&mutex);
if(buffer_has_item==0)
{
sprintf(buffer,"This is %d\n",i++);
buffer_has_item=1;
}
pthread_mutex_unlock(&mutex);
}
}

 

 

 

2)条件变量

1.int pthread_cond_init(pthread_cond_t *cond,pthread_cond_atrr *atrr); atrr 设置属性 NULL默认

  创建chengg返回0,条件变量ID 放在参数cond中,返回其他值意味着出错

2.int phread_cond_destroy(pthread_cond_t *cond) 清除cond指向条件变量的状态,但是存储空间不放

 成功返回0,返回其他值意味着出错

3.int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex) 释放mutex锁,阻塞调用cond指向条件变量的线程

成功返回0,返回其他值意味着出错

4..int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex_t *mutex,struct timespec *abstime) 释放mutex锁,阻塞调用cond指向条件变量的线程直至条件变量获得信号或者经过abstime时间

成功返回0,超过时间返回ETIMEOUT,返回其他值意味着出错

5.phread_cond_signal

int phread_cond_signal(pthread_cond_t *cond)使参数cond指向的条件变量阻塞线程退出阻塞状态

成功返回0,返回其他值意味着出错

6.int phread_cond_broadcast(pthread_cond_t *cond)使所有参数cond指向的条件变量阻塞线程退出阻塞状态

7.当前线程调用线程取消另一个线程

int pthread_cancel(pthread_t thread); 成功返回0,失败返回错误代码

int pthread_setcancelstate(int state,int *oldstate);设置调用函数线程自身的状态,设置成功返回0,失败返回错误

int pthread_setcanceltype(int type,int *oldtype);设置对取消的响应方式,PTHREAD_CANCEL_ASYNCHRONOUS 立刻取消  PTHREAD_CANCEL_DEFERRED 延迟取消至取消点,成功返回0,失败返回错误代码

void pthread_testcancel();设置取消点;若是延迟取消请求挂起,函数取消当前进程

 

8.线程清理工作

void pthread_cleanup_push(void(*rutine)(void*),void *argc)

将程序rutine和arg一起压入当前线程的cleanup处理栈,当当前线程调用pthread_exit或者通过pthread_cancel终止执行时,堆栈中处理程序将按照压栈时反向调用

执行失败,没有返回任何错误报告

void pthread_cleanup_pop(int execute) 从线程的cleanup处理程序堆栈中弹出最上面的一个处理程序执行它

如果执行失败,不会返回错误报告

 

9.线程特定数据处理函数

1)int pthread_key_create(pthreda_key_t *key,void(*dest_routine(void*)))

创建一个进程中所有可以见得关键字, ,当创建一个关键字时,进程中所有线程的这个关键字都是NULL,创建一个线程时,线程所有的关键字都是null

成功返回0,key中保存新创建的关键字,其他值错误

2)int phread_key_delete(phread_key_t key) 删除key指定的关键字,成功返回0,其他值,意味着错误

3)int phread_setspecific(phtead_key_t key,void *pointer)指定由pointer指向的指针指向参数key关键字 成功返回0,其他意味着错误

4)void *phread_getspecific(phtead_key_t key)获取 phread_setspecific指定指针 成功返回0,其他返回意味着错误

5)void * pthread_once_t once_control(PTHREAD_ONCE_INIT;

int pthread_once(pthread_once_t *once_control,void(*init_routine)(void));

保证某些初始化代码只执行一次,总是返回0

9.线程属性

1、初始化一个线程对象的属性
int pthread_attr_init(pthread_attr_t *attr);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
    说  明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。
            pthread_attr_init实现时为属性对象分配了动态内存空间。
    头文件:#include <pthread.h>
2、销毁一个线程属性对象
int pthread_attr_destroy(pthread_attr_t *attr);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
    说  明:经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。
    头文件:#include <pthread.h>

3、获取线程的栈保护区大小
int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            guardsize  返回获取的栈保护区大小
    说  明:获取线程的栈保护区大小
    头文件:#include <pthread.h>
4、设置线程的栈保护区大小
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            guardsize  线程的栈保护区大小
    说  明:参数提供了对栈指针溢出的保护。
            默认为系统页大小
            如果设置为0表示没有保护区。
            大于0,则会为每个使用 attr 创建的线程提供大小至少为 guardsize 字节的溢出保护区
    头文件:#include <pthread.h>
5、获取线程分离状态属性
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr          指向一个线程属性的指针
            detachstate   保存返回的分离状态属性默认为 PTHREAD_CREATE_JOINABLE
    说  明:获取线程分离状态属性,脱离状态下的新城资源在线程结束后就立即释放,而且不能用pthread_join函数来同步终止
    头文件:#include <pthread.h>
6、修改线程分离状态属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr        指向一个线程属性的指针
            detachstat  有两个取值
                        PTHREAD_CREATE_DETACHED(分离)
                        PTHREAD_CREATE_JOINABLE(非分离)
    说  明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。
    头文件:#include <pthread.h>
9、获取线程的作用域
int pthread_attr_getscope(pthread_attr_t *attr, int *scope);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            scope      返回线程的作用域,可能为PTHREAD_SCOPE_PROCESS 或者是PTHREAD_SCOPE_SYSTEM(默认)
    说  明:指定了作用域也就指定了线程与谁竞争资源
    头文件:#include <pthread.h>


10、设置线程的作用域
int pthread_attr_setscope(pthread_attr_t *attr, int scope); 返回值:若是成功返回0,否则返回错误的编号 形 参: attr 指向一个线程属性的指针 guardsize 线程的作用域,可以取如下值 PTHREAD_SCOPE_SYSTEM 与系统中所有进程中线程竞争 PTHREAD_SCOPE_PROCESS 与当前进程中的其他线程竞争 说 明:指定了作用域也就指定了线程与谁竞争资源 头文件:#include <pthread.h>

17、获取线程的调度策略
int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            policy     返回线程的调度策略
    说  明:获取线程的调度策略
    头文件:#include <pthread.h>
18、设置线程的调度策略
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            policy     线程的调度策略,有如下三种:
                        SCHED_FIFO    先入先出策略
                        SCHED_RR      轮转调度,类似于 FIFO,但加上了时间轮片算法
                        SCHED_OTHER      系统默认策略
    说  明:设置线程的调度策略
    头文件:#include <pthread.h>
21、获取线程是否继承调度属性
int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr          指向一个线程属性的指针
            inheritsched  返回继承调度属性的设置
    说  明:获取线程是否继承调度属性
    头文件:#include <pthread.h>
22、设置线程是否继承调度属性
int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            guardsize  设置线程是否继承调度属性
                        PTHREAD_INHERIT_SCHED:调度属性将继承于正创建的线程
                                               attr中的设置将被忽略
                        PTHREAD_EXPLICIT_SCHED 调度属性将被设置为attr中指定的属性值
    说  明:
    头文件:#include <pthread.h>
19、获取线程的调度参数
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            param      返回获取的调度参数,该结构仅有一个从参数,如下
                        struct sched_param 
                        {
                            int sched_priority; /* Scheduling priority */
                        };
    说  明:获取线程的调度参数
    头文件:#include <pthread.h>
20、设置线程的调度参数
int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
            param      要设置的调度参数
    说  明:设置线程的调度参数
    头文件:#include <pthread.h>






 

posted @ 2016-07-04 21:24  ranran1203  阅读(445)  评论(0)    收藏  举报