Linux 线程学习

来源:互联网 发布:2017网络新技术 编辑:程序博客网 时间:2024/06/07 10:06

线程是计算机中独立运行的最小单位,运行时占用很少的系统资源。
一个进程可以拥有多个线程。


每个进程有自已独立的地址空间,多线程情况下,同一进程的线程共享进程的地址空间
线程的切换速度远快于进程的切换速度
线程间通信更加方便省时


linux支持POSIX多线程接口,称为pthread(Posix Thread)。
编写多线程,需头文件pthread.h,链接时使用库libpthread.a


线程共享程序代码,一段代码可以同时被多个线程执行。


创建线程
#include <pthread.h>
int pthread_create(pthread_t* thread,pthread_attr_t* attr,
void* (*start_routine),void *arg);
thread:线程成功创建时,用来返回创建的线程ID
attr:线程的属性
start_routine:函数指针,线程创建后调用的函数。线程函数。
arg:该参数指向传递给线程函数的参数。


创建成功返回0


pthread_t pthread_self():获得本线程ID
int pthread_equal(pthread_t thread1,pthread_t thread2);//两个线程ID是否指向同一线程
int pthread_once(pthread_once_t* once_control,void(*init_routine)(void));
保证init_routine线程函数在进程中仅执行一次。


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int *thread(void* arg)
{
        pthread_t newthid;
        newthid = pthread_self();
        printf("this is a new thread,thread id = %u\n",newthid);
        return NULL;
}
int main()
{
        pthread_t thid;
        printf("main thread,id is %u\n",pthread_self());


        if(pthread_create(&thid,NULL,(void*)thread,NULL) != 0)
        {
                printf("thread creation failed\n");
                exit(1);
        }
        sleep(1);
        exit(0);
}


gcc -o createthread createthread.c -lpthread


pthread_attr_t


typedef struct
{
int detachstate;//表示新创建的线程是否与进程中其他的线程脱离同步
int schedpolicy;//表示新线程的调度策略
struct  sched_param schedparam;
int inheritsched;
int scope;
size_t guardsize;//警戒堆栈大小
int stackaddr_set;//堆栈地址集
void* stackaddr;//堆栈地址
size_t stacksize;//堆栈大小
}pthread_attr_t;



线程终止
1return 从线程函数返回
2调用pthread_exit()


#include <pthread.h>
void pthread_exit(void* retval);


线程同步
一般情况下,进程中各个线程的运行是相互独立的,线程的终止并不会相互通知,
也不会影响其他线程,终止的线程所占用的资源不会随着线程的终止而归还系统,
而是仍为线程所在的进程持有。


#include <pthread.h>
//终止
void pthread_exit(void* retval);
//挂起等待th线程终止
int pthread_join(pthread_t th,void* thread_return);
int pthread_detach(pthread_t th);


私有数据
#include <pthread.h>
int pthread_key_create(pthread_key_t* key,void (*destr_function)(void*));
int pthread_setspecific(pthread_key_t key,const void* pointer));
void* pthread_getspecific(pthread_key_t key);
int pthread_key_delete(pthread_key_t key);


#include <stdio.h>
#include <string.h>
#include <pthread.h>


pthread_key_t key;


void* thread2(void* arg)
{
int tsd = 5;
printf("thread %d is running\n",pthread_self());
pthread_setspecific(key,(void*)tsd);
printf("thread %d returns %d\n",pthread_self(),pthread_getspecific(key));
}


void* thread1(void *arg)
{
int tsd = 0;
pthread_t thid2;


printf("thread %d is running\n",pthread_self());
pthread_setspecific(key,(void*)tsd);
pthread_create(&thid2,NULL,thread2,NULL);
sleep(5);
printf("thread %d returns %d\n",pthread_self(),pthread_getspecific(key));
}


int main()
{
printf_t thid1;
printf("main thread begins running\n");
pthread_key_create(&key,NULL);
pthread_create(&thid1,NULL,thread1,NULL);
sleep(3);
pthread_key_delete(key);
printf("main thread exit\n");
return 0;
}


互斥锁
通过锁机制来实现线程间的同步.
在同一时刻它通常只允许一个线程执行一个关键部分的代码。


pthread_mutex_init:初始化一个互斥锁
pthread_mutex_destroy:注销一个互斥锁
pthread_mutex_lock:加锁,如不成功,阻塞等待
pthread_mutex_unlock:解锁
pthread_mutex_trylock:测试加锁,如不成功立即返回


初始化
静态赋值
pthread_mutex_init


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;


int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t* mutexattr);


int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t * mutex);
int pthread_mutex_unlock(pthread_mutex_t* mutex);
int pthread_mutex_destroy(pthread_mutex_t* mutex);


pthread_mutex_t number_mutex;
int globalnumber;


void write_globalnumber()
{
pthread_mutex_lock(&number_mutex);
globalnumber ++;
pthread_mutex_unlock(&number_mutex);
}


int read_globalnumber()
{
int temp;
pthread_mutex_lock(&number_mutex);
temp = globalnumber;
pthread_mutex_unlock(&number_mutex);
return temp;
}


条件变量
利用线程间共享的全局变量进行同步的一种机制。


pthread_cond_init:
pthread_cond_wait:
pthread_cond_timedwait:
pthread_cond_signal:
pthread_cond_broadcast:
pthread_cond_destroy:


pthread_cond_t cond = PTHREAD_COND_INITIALIZED;


int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,const struct timespec *abstime);


int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);


int pthread_cond_destroy(pthread_cond_t *cond);


#include <stdio.h>
#include <unistd.h>
#include <pthread.h>


pthread_mutex_t mutex;
pthread_cond_t  cond;


void* thread1(void *arg)
{
pthread_cleanup_push(pthread_mutex_unlock,&mutex);
while(1)
{
print("thread1 is running\n");
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
printf("thread1 applied the condition\n");
pthread_mutex_unlock(&mutex);
sleep(4);
}


pthread_cleanup_pop(0);
}


void *thread2(void* arg)
{
while(1)
{
printf("thread2 is running\n");
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
printf("thread2 applied the condigion\n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
}


int main()
{
pthread_t tid1,tid2;
printf("condition variable study!\n");
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
pthread_create(&tid1,NULL,(void*)thread1,NULL);
pthread_create(&tid2,NULL,(void*)thread2,NULL);


do{
pthread_cond_signal(&cond);
}while(1);


sleep(50);
pthread_exit(0);
}


信号与任何线程都是异步的。
int pthread_kill(pthread_t threadid,int signo);
int pthread_sigmask(int how,const sigset_t * newmask,sigset_t *oldmask);
int sigwait(const sigset_t *set,int *sig);


出错
#include <errno.h>
#ifndef errno
extern int errno;
#endif


信号signal是一种软件中断,它提供了一种处理异步事件的方法,也是进间间唯一的异步通信方式。


信号源:
硬件
软件


信号的捕捉和处理
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);


SIGKILL/SIGSTOP两个信号不能被捕捉或忽略


#include <stdio.h>
#include <signal.h>


void handler_sigint(int signo)
{
printf("recv SIGINT\n");
}

int main()
{
signal(SIGINT,handler_sigint);
while(1);
return 0;
}


#include <signal.h>
int sigaction(int signum,const struct sigaction * act,struct sigaction * oldact);


#include <unistd.h>
int pause();




#include <setjmp.h>
int setjmp(jmp_buf env);

void longjmp(jmp_buf env,int val);


保存自用,方便查阅使用

0 0
原创粉丝点击