Linux多线程编程技术总结
1 、线程的创建、终止及控制:
任何进程在启动时就已有了一个主线程,如果需要再生成线程则使用 pthread_create 函数,在该函数中可以指定线程的属性、线程例程、传给线程例程的参数。线程例程是一个用户自定义的函数,及线程执行的代码。当线程例程返回时,线程则结束运行,也可以显示调用 pthread_exit 来退出。线程在创建后可以用 pthread_self 函数获取线程 ID 。函数 pthread_join 使得进程等待线程的终止,调用 pthread_join 后进程将被挂起,直到指定的某个线程(在 pthread_join 的参数 thread 中指定)终止。而 pthread_detach 函数正好相反,它使得进程不必等待线程的结束,从而允许进程继续执行别的操作,被 detach 的线程在执行结束后其占用的资源由系统自动收回。
2 、线程间的互斥:
互斥操作 ,就是对某段代码或某个变量修改的时候只能有一个线程在执行这段代码,其他线程不能同时进入这段代码或同时修改变量。 pthread 常用 pthread_mutex 互斥体来实现线程互斥操作。 pthread_mutex_init 函数用于初始化一个互斥体变量。 pthread_mutex_lock 函数用于给互斥体变量上锁,如果上锁时互斥体已经被被的线程锁住了,那么调用该函数的线程将被阻塞直到互斥体被解锁为止。而 pthread_mutex_trylock 则是试图锁住互斥体,但在互斥体已经被加锁时不会造成阻塞,而是迅速返回。 pthread_mutex_unlock 函数对互斥体解锁。 pthread_mutex_destroy 则用来释放互斥体所占资源。
3 、线程的同步:
同步就是若干个线程等待某个事件的发生,当该事件发生时,一起开始继续执行。在 Linux 线程中用条件变量来实现同步。函数 pthread_cond_init 用来创建一个条件变量。 pthread_cond_wait 和 pthread_cond_timewait 用来等待条件变量被设置,值得注意的是这两个等待调用需要一个已经上锁的互斥体 mutex ,这是为了防止在真正进入等待状态之前别的线程有可能设置该条件变量而产生竞争。 pthread_cond_broadcast 用于设置条件变量,即使事件发生,并使得所有等待该事件的线程不再阻塞。而 pthread_cond_signal 则是用解除某一个等待线程的阻塞状态。 pthread_cond_destroy 用来释放一个条件变量的资源。
4 、生产者——消费者多线程技术实现:
# include < stdio. h>
# include < pthread. h>
# define BUFFER_SIZE 16
struct prodcons {
int buffer[ BUFFER_SIZE] ;
pthread_mutex_t lock;
int readpos, writepos;
pthread_cond_t notempty;
pthread_cond_t notfull;
} ;
void init ( struct prodcons * b) {
pthread_mutex_init ( & b- > lock, NULL ) ;
pthread_cond_init ( & b- > notempty, NULL ) ;
pthread_cond_init ( & b- > notfull, NULL ) ;
b- > readpos= 0;
b- > writepos= 0;
}
void put( struct prodcons * b, int data) {
{
pthread_mutex_lock ( & b- > lock) ;
if ( ( b- > writepos+ 1) % BUFFER_SIZE= = b- > readpos) {
pthread_cond_wait ( & b- > notfull, & b- > lock) ;
}
b- > buffer[ b- > writepos] = data;
b- > writepos+ + ;
if ( b- > writepos> = BUFFER_SIZE)
b- > writepos= 0;
pthread_cond_signal ( & b- > notempty) ;
pthread_mutex_unlock ( & b- > lock) ;
}
int get( struct prodcons * b)
{
int data;
pthread_mutex_lock ( & b- > lock) ;
if ( b- > writepos= = b- > readpos) {
pthread_cond_wait ( & b- > notempty, & b- > lock) ;
}
data= b- > buffer[ b- > readpos] ;
b- > readpos+ + ;
if ( b- > readpos> = BUFFER_SIZE)
b- > readpos= 0;
pthread_cond_signal ( & b- > notfull) ;
pthread_mutex_unlock ( & b- > lock) ;
return data;
}
# define OVER ( - 1)
struct prodcons buffer;
void * producer( void * data)
{
int n;
for ( n= 0; n< 10000; n+ + )
{
printf ( “% d- - - - > / n”, n) ;
put( & buffer, n) ;
}
put( & buffer, OVER) ;
return NULL ;
}
void * consumer( void * data)
{
int d;
while ( 1)
{
d= get( & buffer) ;
if ( d= = OVER)
break ;
printf ( “- - - - > % d/n”, d) ;
}
return NULL ;
}
int main( void )
{
pthread_t th_a, th_b;
void * retval;
init( & buffer) ;
pthread_create ( & th_a, NULL , producer, 0) ;
pthread_create ( & th_b, NULL , consumer, 0) ;
pthread_join ( th_a, & retval) ;
pthread_join ( th_b, & retval) ;
return 0;
}