Outline
- 1.線程特點
- 2.pthread創建
- 3.pthread終止
- 4.mutex互斥量使用框架
- 5.cond條件變量
- 6.綜合實例
pthread_cond_destroy
-
while (1) {
-
lock(lock_for_X);
-
-
if (X is not empty) {
-
unlock(lock_for_X);
-
break;
-
} else { //X is empty, loop continues
-
unlock(lock_for_X);
-
sleep(10);
-
}
-
}
-
//X is not empty, loop ends
- process(X);
-
while (1) {
-
lock(lock_for_X);
-
if (X is not empty) {
-
unlock(lock_for_X);
-
break;
-
} else {
-
unlock(lock_for_X); //must
called before my_wait(), otherwise no one can acquire the lock and make
change to X
-
-------------------------------------->窗口,由於已經解鎖,其他程序可能改變X,並且試圖喚醒mywait,但在一個繁忙的系統中,可能此時my_還沒被調用!
-
my_wait(); //go to sleep and wait for the
notification
-
}
- }
-
lock(lock_for_X);
-
while (X is empty) {
-
pthread_cond_wait(&qready, &lock_for_X);
-
}
- unlock(lock_for_X);
-
while(1) {
-
lock(lock_for_X);
-
dequeue(X);
-
unlock(lock_for_X);
- }
-
/*
-
* =====================================================================================
-
*
-
* Filename: pthread.c
-
*
-
* Description:
-
*
-
* Version: 1.0
-
* Created: 08/17/11
11:06:35
-
* Revision: none
-
* Compiler: gcc
-
*
-
* Author: YOUR NAME (),
-
* Company:
-
*
-
* =====================================================================================
-
*/
-
#include <stdio.h>
-
#include <pthread.h>
-
#include <error.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <string.h>
-
-
pthread_cond_t qready;
-
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
-
-
struct foo {
-
int cnt;
-
pthread_mutex_t f_lock;
-
};
-
-
void cleanup(void *arg)
-
{
-
printf("clean up: %s\n", (char *)arg);
-
}
-
-
void printids(char *str)
-
{
-
printf("%s pid = %u tid = %u / 0x%x\n",
-
str, (unsigned int)getpid(), (unsigned int)pthread_self(), (unsigned int)pthread_self());
-
}
-
-
void *thread1(void *arg)
-
{
-
pthread_mutex_lock(&qlock);
-
pthread_cond_wait(&qready, &qlock);
-
pthread_mutex_unlock(&qlock);
-
-
printids("thread1:");
-
-
pthread_cleanup_push(cleanup, "thread 1 first cleanup handler");
-
pthread_cleanup_push(cleanup, "thread 1 second cleanup handler");
-
printf("thread 1 push complete!\n");
-
-
pthread_mutex_lock(&((struct
foo *)arg)->f_lock);
-
((struct foo *)arg)->cnt ;
-
printf("thread1: cnt = %d\n", ((struct
foo *)arg)->cnt);
-
pthread_mutex_unlock(&((struct
foo *)arg)->f_lock);
-
-
if (arg)
-
return ((void *)0);
-
-
pthread_cleanup_pop(0);
-
pthread_cleanup_pop(0);
-
-
pthread_exit((void *)1);
-
}
-
-
void *thread2(void *arg)
-
{
-
int exit_code = -1;
-
printids("thread2:");
-
-
printf("Now unlock thread1\n");
-
-
pthread_mutex_lock(&qlock);
-
pthread_mutex_unlock(&qlock);
-
pthread_cond_signal(&qready);
-
-
printf("Thread1 unlocked\n");
-
-
pthread_cleanup_push(cleanup, "thread 2 first cleanup handler");
-
pthread_cleanup_push(cleanup, "thread 2 second cleanup handler");
-
printf("thread 2 push complete!\n");
-
-
if (arg)
-
pthread_exit((void *)exit_code);
-
-
pthread_cleanup_pop(0);
-
pthread_cleanup_pop(0);
-
-
pthread_exit((void *)exit_code);
-
}
-
-
int main(int argc, char *argv[])
-
{
-
int ret;
-
pthread_t tid1, tid2;
-
void *retval;
-
struct foo *fp;
-
-
ret = pthread_cond_init(&qready, NULL);
-
if (ret != 0) {
-
printf("pthread_cond_init error: %s\n", strerror(ret));
-
return -1;
-
}
-
-
-
-
if ((fp = malloc(sizeof(struct
foo))) == NULL) {
-
printf("malloc failed!\n");
-
return -1;
-
}
-
-
if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
-
free(fp);
-
printf("init mutex failed!\n");
-
}
-
-
pthread_mutex_lock(&fp->f_lock);
-
-
ret = pthread_create(&tid1, NULL, thread1, (void *)fp);
-
if (ret != 0) {
-
printf("main thread error: %s\n", strerror(ret));
-
return -1;
-
}
-
ret = pthread_create(&tid2, NULL, thread2, (void *)1);
-
if (ret != 0) {
-
printf("main thread error: %s\n", strerror(ret));
-
return -1;
-
}
-
-
-
ret = pthread_join(tid2, &retval);
-
if (ret != 0) {
-
printf("pthread join falied!\n");
-
return -1;
-
}
-
else
-
printf("thread2 exit code %d\n", (int)retval);
-
-
fp->cnt = 1;
-
printf("main thread: cnt = %d\n",fp->cnt);
-
-
pthread_mutex_unlock(&fp->f_lock);
-
-
sleep(1); //there is no
guarantee the main thread will run before the newly created thread, so we wait for a while
-
printids("main thread:");
-
-
printf("Press to exit\n");
-
-
ret = pthread_cond_destroy(&qready);
-
if (ret != 0) {
-
printf("pthread_cond_destroy error: %s\n", strerror(ret));
-
return -1;
-
}
-
-
getchar();
-
return 0;
- }