跨平台线程库——pThread
来源:互联网 发布:天书世界坐骑进阶数据 编辑:程序博客网 时间:2024/05/18 03:26
#include <pthread.h>
int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
新的线程可以通过调用pthread_exit显式结束,或者通过start_routine return来隐式结束。其中后者等价于调用pthread_exit并以start_routine 的返回值作为退出码。
新线程的初始信号状态继承自他的创建线程,并且没有挂起的信号。pthread-win32暂时未实现信号量。
attr参数指明新线程的属性,如果attr=NULL,则使用默认属性:新线程是joinable(not detached),和默认的调度策略(非实时)
返回值:如果成功,新线程的指针会被存储到thread的参数中,并返回0。如果错误则一个非0的错误码返回。
如果返回EAGAIN,没有足够的系统资源创建一个线程,或者已经存在大于PTHREAD_THREADS_MAX个活跃线程。
2. pthread_exit
#include <pthread.h>
pthread_exit结束调用线程的执行.所有通过pthread_cleanup_push设置的清除句柄将会被反序执行(后进先出)。
所以key值非空的线程特定数据Finalization functions被调用(参见pthread_key_create)。
最后调用线程被终止。
retval是这个线程结束的返回值,可以通过在别的线程中调用pthread_join来获取这个值。
没有返回值。
3. pthread_join
#include <pthread.h>
int pthread_join(pthread_t th, void **thread_return);
挂载一个在执行的线程直到该线程通过调用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.
5.pthread_cond
#include <pthread.h>
pthread_cond_init初始化条件变量,通过cond_attr,如果cond_attr是null则使用默认属性。也可以通过常量PTHREAD_COND_INITIALIZER静态初始化。
pthread_cond_signal激活一个正在等待条件变量cond的线程。如果没有线程在等待则什么也不会发生,如果有多个线程在等待,则只能激活一个线程,带未指定是哪个线程(根据操作系统自己的调度策略选择)。
pthread_cond_broadcast激活所有在等待条件变量cond的线程。
pthread_cond_wait自动解锁mutex(pthread_unlock_mutex)等待条件变量cond发送。线程的执行被挂起不消耗cpu时间直到cond发送。在wait的入口mutex必须被锁住。
在重新回到线程前,pthread_cond_wait会重新获得mutex(pthread_lock_mutex).解锁mutex和挂起是自动进行的。因此,如果所有线程在发送cond前都申请mutex的话,
这种wait的内部实现机制能够保证在线程锁住mutex和线程wait之间不会有cond发送操作发送。
pthread_cond_timedwait同pthread_cond_wait,只是多了个超时设置,如果超时,则重新获取mutex并且返回ETIMEDOUT,时间为绝对时间。
pthread_cond_destroy销毁一个条件变量。必须没有线程在wait该条件变量。
condition函数是异步信号不安全的,容易产生死锁,必须自己控制调用流程避免死锁。
6.semaphore
sem_init:初始化信号量,pshared表示该信号量是否只属于当前进程(pshared==0),如果pshared不为0则表示可以在进程间共享。value表示该信号量的初始值。
sem_wait:如果信号量的值大于0,则自动减1并立即返回。否则线程挂起直到sem_post或sem_post_multiple增加信号量的值。
sem_timedwait:同sem_wait,只是多了个超时设置,如果超时,首先将全局变量errno设为ETIMEDOUT,然后返回-1.
sem_trywait:如果信号量的值大于0,将信号量减1并立即返回,否则将全局变量errno设为ETIMEDOUT,然后返回-1。sem_trywait不会阻塞。
sem_post:释放一个正在等待该信号量的线程,或者将该信号量+1.
sem_post_multiple:释放多个正在等待的线程。如果当前等待的线程数n小于number,则释放n个线程,并且该信号量的值增加(number - n).
sem_get_value:返回信号量的值。在pthread-win32实现中,正值表示当前信号量的值,负值的绝对值表示当前正在等待该信号量的线程数。虽然在POSIX不需要这么表示,但是也是同样含义。
信号量(sem)与条件变量(cond)的主要差别在于,条件变量等待必须在发送之前,否则容易出现死锁,而信号量等待可以在发送之后执行。一句话概括信号量对于操作的时序没有要求。
1.
#include <QCoreApplication>#include <iostream>#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 <stdio.h>#include <Windows.h>#include "pthread.h"#include <ctype.h>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;}
3.
#include <stdio.h>#include <Windows.h>#include "pthread.h"#include "semaphore.h"#include <ctype.h>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;}
http://www.cppblog.com/saha/articles/189802.html
- 跨平台线程库——pThread
- 跨平台多线程库pthread
- 线程学习——Pthread
- 线程——create pthread
- 操作系统实验——浅谈pthread库线程创建
- pthread 库学习—1:进程与线程
- Pthread线程库--NPTL
- pthread线程库简介
- pthread线程库
- linux pthread 线程库
- pthread 线程库
- Pthread线程库简介
- 专题一 Linux下多线程编程——使用Pthread线程库
- pthread线程的加锁问题——thread locking problems
- Unix高级IO之多线程编程 ——pthread解析
- Pthread线程 —— 多线程同步 互斥锁(mutex)
- Pthread 线程 —— 多线程同步 条件变量(cond)
- iOS之多线程——概念、pthread、NSThread、GCD
- Android控制水平方向字体缩放android:textScaleX
- matlab2014a中help与参考页翻译 find
- 分布式-基础之一-分布式系统调用
- Kinds of Fuwas
- 01.javascript中字符串常用操作总结、JS字符串操作大全
- 跨平台线程库——pThread
- 收录常用正则表达式
- 水池数目
- NYOJ - 喷水装置(二)
- iOS开发实战:如何将非ARC的项目转换成ARC项目
- 文章标题
- matlab2014a中help与参考页翻译 roots
- 支付宝在ios中的应用1
- MVC设计模式与多层架构