struct foo *fp;
err = pthread_create(&tid1, NULL, thr_fn1, NULL);
if (err != 0)
err_quit("can\'t create thread 1: %s\\n", strerror(err));
err = pthread_join(tid1, (void *)&fp);
if (err != 0)
err_quit("can\'t join with thread 1: %s\\n", strerror(err));
sleep(1);
printf("parent starting second thread\\n");
err = pthread_create(&tid2, NULL, thr_fn2, NULL);
if (err != 0)
err_quit("can\'t create thread 2: %s\\n", strerror(err));
sleep(1);
printfoo("parent:\\n", fp);
exit(0);
}
注意,pthread_create 和 pthread_exit函数的无类型指针可以传递复杂的结构信息,但这个结构所使用的内存在调用者完成后必须仍然有效(分配在堆上或者是静态变量),否则就会出现使用无效的错误。这段代码中thr_fn1函数中变量foo分配在栈上,但该线程退出后,主线程通过pthread_join获取foo的地址并进行操作(调用printfoo函数时)就会出现错误,因为此时thr_fn1已经退出它的栈已经被销毁。
5.如何通过一个线程让另外一个线程退出?
调用pthread_cancel函数将导致tid所指向的线程终止运行。但是,一个线程可以选择忽略其它线程控制该线程何时退出。注意,该函数并不等待线程终止,它仅仅提出要求。
#include
int pthread_cancel(pthread_t tid);
Returns: 0 if OK, error number on failure
6.如何实现线程退出时的清理动作?
线程可以建立多个清理处理程序,这些程序记录在栈中,也就是说他们的执行顺序与注册顺序想法。使用如下函数注册清理函数:
void pthread_cleanup_push(void (*rtn)(void *), void *arg);
void pthread_cleanup_pop(int execute);
rtn将被调用,并传以arg参数,引起该函数调用的情况如下:
o 调用pthread_exit
o 对于退出请求的反应
o 以非0参数调用pthread_cleanup_push
如果pthread_cleanup_pop的参数非0则仅仅移除该处理函数而不执行。
如果函数已经处于分离状态,则当它退出时线程底层的存储资源会被立即回收。处于分离状态的线程,如果调用pthread_join来等待其退出将会出现错误。
通过下列函数可以让进程处于分离状态:
#include
int pthread_detach(pthread_t tid);
Returns: 0 if OK, error number on failure
7.Unix系统如何实现线程之间的同步?
使用pthreads mutual-exclusion interfaces。引入了mutex,用pthread_mutex_t类型来表示。在使用这个变量之前,我们首先要将其初始化,或者赋值为 PTHREAD_MUTEX_INITIALIZER(仅仅用于静态分配的mutexs),或者调用pthread_mutex_init。如果我们动态的为mutex分配空间(例如通过调用malloc),我们需要在调用free释放内存之前调用pthread_mutex_destroy。
函数定义如下:
以下是代码片段: #include int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); Both return: 0 if OK, error number on failure |
初始化mutex时参数attr用来指定mutex的属性,要使用默认值将它设置为NULL。
使用如下函数对mutex进行加锁或解锁:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
All return: 0 if OK, error number on failure
注意当mutex已经被加锁则 pthread_mutex_lock会阻塞。如果一个线程无法忍受阻塞,可以调用pthread_mutex_trylock来加锁,加锁失败则立即返回EBUSY。
8.什么情况会发生线程死锁,如何避免死锁?
如果一个线程对mutex加两次锁则显然会导致死锁。但实际上死锁的情况要复杂的多:when we use more than one mutex in our programs, a deadlock can occur if we allow one thread to hold a mutex and block while trying to lock a second mutex at the same time that another thread holding the second mutex tries to lock the first mutex. Neither thread can proceed, because each needs a resource that is held by the other, so we have a deadlock.
死锁可以通过控制加锁的顺序来避免。有两个mutex A和B,如果所有的线程总是先对A加锁再对B加锁就不会产生死锁。但实际应用中可能很难保证这种顺序加锁的方式,这种情况下,可以使用pthread_mutex_trylock来避免死锁的发生。
9.读写锁的使用方法。
读写锁的初始化与销毁:
以下是代码片段: #include int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); Both return: 0 if OK, error number on failure |
原文转自:http://blogread.cn/it/article/3344