#include
int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
挂载一个在执行的线程直到该线程通过调用pthread_exit或者cancelled结束。(阻塞的方式等待指定的现成结束,释放线程资源)
如果thread_return不为空,则线程th的返回值会保存到thread_return所指的区域。
th的返回值是它给pthread_exit的参数,或者是pthread_canceled 如果是被cancelled的。
被依附的线程th必须是joinable状态。一定不能是detached通过使用pthread_detach或者pthread_create中使用pthread_create_detached属性。
当一个joinable线程结束时,他的资源(线程描述符和堆栈)不会被释放直到另一个线程对它执行pthread_join操作。
如果成功,返回值存储在thread_return中,并返回0,否则返回错误码:
ESRCH:找不到指定线程
EINVAL:线程th是detached或者已经存在另一个线程在等待线程th结束
EDEADLK:th的参数引用它自己(即线程不能join自身)
4.pthread_cancel
Cancellation是一种一个线程可以结束另一个线程执行的机制。更确切的说,一个线程可以发生Cancellation请求给另一个线程。
根据线程的设置,收到请求的线程可以忽视这个请求,立即执行这个请求或者延迟到一个cancellation点执行。
当一个线程执行Cancellation请求,相当于在那个点执行pthread_exit操作退出:所有cleanup句柄被反向调用,所有析构函数被调用结束线程并返回pthread_canceled.
#include
#include
#include "pthread.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *Func1(void *);
void *Func2(void *);
int i = 1;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
#ifdef WIN32
#ifdef PTW32_STATIC_LIB
pthread_win32_process_attach_np();
pthread_win32_thread_attach_np();
#endif
#endif
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1,NULL,Func1,(void*)NULL);
pthread_create(&thread2,NULL,Func2,(void*)NULL);
pthread_join(thread2,NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
#ifdef WIN32
#ifdef PTW32_STATIC_LIB
pthread_win32_process_detach_np();
pthread_win32_thread_detach_np();
#endif
#endif
system("Pause");
return a.exec();
}
void *Func1(void *junk)
{
for(i = 1;i <= 9;i++)
{
if(i%3==0)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
else
{
std::cout << "thread1: " << i << std::endl;
}
}
return NULL;
}
void *Func2(void *junk)
{
while(i<9)
{
if(i%3!=0)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}
else
{
std::cout << "thread2: " << i << std::endl;
}
}
return NULL;
}
#include
#include
#include "pthread.h"
#include
typedef struct arg_set
{
char *fname;
int count;
int tid;
}ARG_SET;
bool bWait = false;
ARG_SET *mailbox = NULL;
pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t write_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t read_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t write_cond = PTHREAD_COND_INITIALIZER;
void main(int ac, char *av[])
{
pthread_win32_process_attach_np();
pthread_win32_thread_attach_np();
pthread_t t1, t2, t3;
ARG_SET args1, args2, args3;
void *count_words(void *);
int reports_in = 0;
int total_words = 0;
if (4 != ac)
{
printf("usage: %s file1 file2 file3\n", av[0]);
return;
}
args1.fname = av[1];
args1.count = 0;
args1.tid = 1;
pthread_create(&t1, NULL, count_words, (void *)&args1);
args2.fname = av[2];
args2.count = 0;
args2.tid = 2;
pthread_create(&t2, NULL, count_words, (void *)&args2);
args3.fname = av[3];
args3.count = 0;
args3.tid = 3;
pthread_create(&t3, NULL, count_words, (void *)&args3);
while(reports_in < 3)
{
printf("MAIN: waiting for flag to go up\n");
pthread_mutex_lock(&read_lock);
bWait = true;
pthread_cond_wait(&read_cond, &read_lock);
bWait = false;
pthread_mutex_unlock(&read_lock);
printf("MAIN: wow! flag was raised, I have the lock\n");
printf("MAIN: %7d: %s\n", mailbox->count, mailbox->fname);
total_words += mailbox->count;
Sleep(10);
printf("MAIN: Ok, I've read the thread %d mail\n", mailbox->tid);
pthread_mutex_lock(&write_lock);
pthread_cond_signal(&write_cond);
pthread_mutex_unlock(&write_lock);
printf("MAIN: raising write flag\n");
reports_in++;
}
printf("%7d: total words\n", total_words);
pthread_mutex_destroy(&read_lock);
pthread_mutex_destroy(&write_lock);
pthread_cond_destroy(&read_cond);
pthread_cond_destroy(&write_cond);
pthread_win32_thread_detach_np();
pthread_win32_process_detach_np();
system("pause");
}
void *count_words(void *a)
{
ARG_SET *args = (ARG_SET*)a;
FILE *fp;
int c, prevc = '\0';
if (NULL != (fp = fopen(args->fname, "r")))
{
while((c = getc(fp)) != EOF)
{
if (!isalnum(c) && isalnum(prevc))
{
args->count++;
}
prevc = c;
}
fclose(fp);
}
else
{
perror(args->fname);
}
printf("COUNT %d: waiting to get lock\n", args->tid);
pthread_mutex_lock(&write_lock);
if (NULL != mailbox)
{
printf("COUNT %d: oops..mailbox not empty. wait for signal\n", args->tid);
pthread_cond_wait(&write_cond, &write_lock);
}
printf("COUNT %d: OK, I can write mail\n", args->tid);
mailbox = args;
while (!bWait)
{
Sleep(1);
}
pthread_mutex_lock(&read_lock);
pthread_cond_signal(&read_cond); /* raise the flag */
pthread_mutex_unlock(&read_lock);
printf("COUNT %d: raising read flag\n", args->tid);
pthread_mutex_unlock(&write_lock); /* release the mailbox */
printf("COUNT %d: unlocking box\n", args->tid);
return NULL;
}
#include
#include
#include "pthread.h"
#include "semaphore.h"
#include
typedef struct arg_set
{
char *fname;
int count;
int tid;
}ARG_SET;
ARG_SET *mailbox = NULL;
static sem_t sem_write;
static sem_t sem_read;
void main(int ac, char *av[])
{
pthread_win32_process_attach_np();
pthread_win32_thread_attach_np();
pthread_t t1, t2, t3;
ARG_SET args1, args2, args3;
void *count_words(void *);
int reports_in = 0;
int total_words = 0;
if (4 != ac)
{
printf("usage: %s file1 file2 file3\n", av[0]);
return;
}
if (-1 == sem_init(&sem_read, 0 , 1)
|| -1 == sem_init(&sem_write, 0, 0))
{
return;
}
args1.fname = av[1];
args1.count = 0;
args1.tid = 1;
pthread_create(&t1, NULL, count_words, (void *) &args1);
args2.fname = av[2];
args2.count = 0;
args2.tid = 2;
pthread_create(&t2, NULL, count_words, (void *) &args2);
args3.fname = av[3];
args3.count = 0;
args3.tid = 3;
pthread_create(&t3, NULL, count_words, (void *) &args3);
while(reports_in < 3)
{
printf("MAIN: waiting for sub thread write\n");
sem_wait(&sem_write);
printf("MAIN: %7d: %s\n", mailbox->count, mailbox->fname);
total_words += mailbox->count;
if ( mailbox == &args1)
pthread_join(t1,NULL);
if ( mailbox == &args2)
pthread_join(t2,NULL);
if ( mailbox == &args3)
pthread_join(t3,NULL);
mailbox = NULL;
printf("MAIN: Ok,I have read the mail\n");
sem_post(&sem_read);
reports_in++;
}
printf("%7d: total words\n", total_words);
sem_destroy(&sem_read);
sem_destroy(&sem_write);
pthread_win32_thread_detach_np();
pthread_win32_process_detach_np();
system("pause");
}
void *count_words(void *a)
{
struct arg_set *args = (arg_set *)a; /* cast arg back to correct type */
FILE *fp;
int c, prevc = '\0';
if ( (fp = fopen(args->fname, "r")) != NULL )
{
while( ( c = getc(fp)) != EOF )
{
if ( !isalnum(c) && isalnum(prevc) )
{
args->count++;
}
prevc = c;
}
fclose(fp);
} else
perror(args->fname);
printf("COUNT %d: waiting for main thread read the mail\n", args->tid);
sem_wait(&sem_read);
printf("COUNT %d:OK,I can write mail\n", args->tid);
mailbox = args; /* put ptr to our args there */
printf("COUNT %d: Finished writting\n", args->tid);
sem_post(&sem_write);
return NULL;
}