浅说linux线程

1.int pthread_create(pthread_t * thread, pthread_attr_t * attr,

void * (*start_routine)(void *), void * arg)

线程创建,pthread_create()创建的线程并不具备与主线程(即调用pthread_create()的线程)同样的执行序列,而是使其运行start_routine(arg)函数;尽管arg是void *类型的变量,但它同样可以作为任意类型的参数传给start_routine()函数。

例:char message[] =”hello world!”;

res = pthread_create(&tid,NULL,thread_function,(void*)message);//传递参数message

2. int pthread_join(pthread_t th, void **thread_return)

pthread_join()的调用者将挂起并等待th线程终止,retval是pthread_exit()调用者线程(线程ID为th)的返回值,如果thread_return不为NULL,则*thread_return=retval。需要注意的是一个线程仅允许唯一的一个线程使用pthread_join()等待它的终止,并且被等待的线程应该处于可join状态,即非DETACHED状态。

这是因为pthread_join使一个线程等待另一个线程结束。如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的两个线程没有机会开始执行就结束了,所以没有执行子线程。加入pthread_join后,主线程会一直等待直到等待的子线程结束自己才结束,使创建的线程有机会执行。

主线程结束,整个进程就要结束,其他线程也会被结束。

例: if(thread[0] !=0) {

pthread_join(thread[0],NULL); //调用的主线程等待thread[0]线程运行结束。printf(“Thread 1 is over /n”); }

例:void *thread_result; //返回值

res = pthread_join(tid,&thread_result);

void *thread_function(void* arg){

printf(“thread is running now,arg is %s/n”,(char*)arg);

printf(“thread is running now,arg is change %s/n”,(char*)arg);

pthread_exit((void*)”thank you wait fo me!”); //参数传个pthread_join的thread_result

}

3.互斥锁

有两种方法创建互斥锁,静态方式和动态方式。POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,方法如下:pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;在LinuxThreads实现中,pthread_mutex_t是一个结构,而PTHREAD_MUTEX_INITIALIZER则是一个结构常量。

动态方式是采用pthread_mutex_init()函数来初始化互斥锁,API定义如下:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)其中mutexattr用于指定互斥锁属性(见下),如果为NULL则使用缺省属性。

pthread_mutex_destroy()用于注销一个互斥锁,API定义如下:int pthread_mutex_destroy(pthread_mutex_t *mutex)销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。由于在Linux中,互斥锁并不占用任何资源,因此LinuxThreads中的pthread_mutex_destroy()除了检查锁状态以外(锁定状态则返回EBUSY)没有其他动作。

锁操作主要包括加锁pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁pthread_mutex_trylock()三个,不论哪种类型的锁,都不可能被两个不同的线程同时得到,而必须等待解锁。对于普通锁和适应锁类型,解锁者可以是同进程内任何线程;而检错锁则必须由加锁者解锁才有效,否则返回EPERM;对于嵌套锁,文档和实现要求必须由加锁者解锁,但实验结果表明并没有这种限制,这个不同目前还没有得到解释。在同一进程中的线程,如果加锁后没有解锁,则任何其他线程都无法再获得锁。

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

pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待。

例:pthread_mutex_t mut;

pthread_mutex_lock(&mut);

pthread_mutex_unlock(&mut);

主函数,调用函数中先初始化锁:

pthread_mutex_init(&mut,NULL);

/*thread_example.c : c multiple thread programming in linux */#include <unistd.h>#include <stdio.h>#include <stdlib.h>

#include <pthread.h>

#include <string.h>

#define MAX1 10#define MAX2 30

pthread_t thread[2];pthread_mutex_t mut;int number=0, i;

void *thread1() // commen3{ printf (“thread1 : I’m thread 1/n”);

for (i = 0; i < MAX1; i++) { printf(“thread1 : number = %d i=%d/n”,number,i); pthread_mutex_lock(&mut); //加锁thread2不能运行 number++; pthread_mutex_unlock(&mut); sleep(2); }

printf(“thread1 :Is main function waiting for me acomplishing task? /n”); pthread_exit(NULL);}

void *thread2() // commen4{ printf(“thread2 : I’m thread 2/n”);

for (i = 0; i < MAX2; i++) { printf(“thread2 : number = %d i=%d/n”,number,i); pthread_mutex_lock(&mut); //加锁thread1不能运行 number++; pthread_mutex_unlock(&mut); sleep(3); }

printf(“thread2 :Is main function waiting for me to acomplish task ?/n”); pthread_exit(NULL);}

void thread_create(void) //comment2{ int temp; memset(&thread, 0, sizeof(thread)); /*创建线程*/ if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)

printf(“线程1创建失败!/n”); //进入commen3 else printf(“Thread 1 is established/n”);

if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0)

printf(“线程2创建失败”); //进入commen4 else printf(“Thread 2 is established/n”);}

void thread_wait(void) //comment5{ /*等待线程结束*/ if(thread[0] !=0) {

pthread_join(thread[0],NULL); printf(“Thread 1 is over /n”); //main函数等待thread1运行完 } if(thread[1] !=0) {

pthread_join(thread[1],NULL); printf(“Thread 2 is over/n”); // main函数等待thread2运行完 }}

int main(){ /*用默认属性初始化互斥锁*/ pthread_mutex_init(&mut,NULL); //comment1

printf(“I am the main funtion,and I am establishing threads. Ha-ha/n”); thread_create(); //进入comment2 printf(“I am the main funtion,and I am waiting for thread to accomplish task. Ha-ha/n”); thread_wait(); //进入comment5

return 0;}

运行:这样就简单实现了thread1和thread2交替运行。

注:sleep函数在这里很主要,否则不能实现交替运行。自己试了不加锁,让它们的sleep值一样,一样可以交替运行,挺奇怪的。

4.退出:

1. exit, _Exit, _exit用于中止当前进程,而非线程

2. 中止线程可以有三种方式:

a. 在线程函数中return

b. 被同一进程中的另外的线程Cancel掉

c. 线程调用pthread_exit函数

3. pthread_exit和pthread_join函数的用法:

a. 线程A调用pthread_join(B, &rval_ptr),被Block,进入Detached状态(如果已经进入Detached状态,则pthread_join函数返回EINVAL)。如果对B的结束代码不感兴趣,rval_ptr可以传NULL。

b. 线程B调用pthread_exit(rval_ptr),退出线程B,结束代码为rval_ptr。注意rval_ptr指向的内存的生命周期,不应该指向B的Stack中的数据。

c. 线程A恢复运行,pthread_join函数调用结束,线程B的结束代码被保存到rval_ptr参数中去。如果线程B被Cancel,那么rval_ptr的值就是PTHREAD_CANCELLED。

例子:

#include <unistd.h>

#include <stdio.h>

#include <pthread.h>

pthread_t tid;

void *reval;

char message[] = “this is param”;

void *thread_function(void *);

main(){

pthread_create(&tid , NULL ,thread_function,(void*) message);

printf(“wait for thread run complete/n”);

pthread_join(tid,&reval); //等待thread运行完

printf(“join success,this is pthead_exit::%s”,(char*)reval); //exit返回值

return 0;

}

void *thread_function(void *){

printf(“create thread successful!!!/n”);

printf(“this is id %d/n”,pthread_self());

printf(“this is param :%s/n”,(char*)message); //创建时传递的参数

pthread_exit((void *)”thread exit successful!!/n”);

}

同时也用对她的怀念来惩罚自己。

浅说linux线程

相关文章:

你感兴趣的文章:

标签云: