UNP函数笔记十六: 线程
来源:互联网 发布:今日股市数据 编辑:程序博客网 时间:2024/05/16 12:17
第二十六章 线程:
#include <pthread.h>int pthread_create(pthread_t * tid, const pthread_attr_t * attr, void * (*func)(void *), void * arg); success return 0, error return Exxx, will not modify errno#include <pthread.h>int pthread_join(pthread_t tid, void ** status); success return 0, error return Exxx, will not modify errno#include <pthread.h>pthread_t pthread_self(void);#include <pthread.h>int pthread_detach(pthread_t tid); success return 0, error return Exxx, will not modify errno#include <pthread.h>void pthread_exit(void * status);#include <pthread.h>pthread_once_t once = PTHREAD_ONCE_INIT;int pthread_once(pthread_once_t * onceptr, void (*init)(void)); success return 0, error return Exxx, will not modify errno#include <pthread.h>int pthread_key_create(pthread_key_t * keyptr, void (*destructor)(void * value)); success return 0, error return Exxx, will not modify errno#include <pthread.h>void * pthread_getspecific(pthread_key_t key); return thread private data, no data match with key return NULLint pthread_setspecific(pthread_key_t key, const void * value); success return 0, error return Exxx, will not modify errno#include <pthread.h>int pthread_mutex_lock(pthread_mutex_t * mptr); success return 0, error return Exxx, will not modify errnoint pthread_mutex_unlock(pthread_mutex_t * mptr); success return 0, error return Exxx, will not modify errno#include <pthread.h>int pthread_cond_wait(pthread_cond_t * cptr, pthread_mutex_t * mptr); success return 0, error return Exxx, will not modify errnoint pthread_cond_signal(pthread_cond_t * cptr); success return 0, error return Exxx, will not modify errnoPTHREAD_COND_INITIALIZER#include <pthread.h>int pthread_cond_broadcast(pthread_cond_t * cptr); success return 0, error return Exxx, will not modify errnoint pthread_cond_timedwait(pthread_cond_t * cptr, pthread_mutex_t * mptr, const struct timespec * abstime); success return 0, error return Exxx, will not modify errno struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanosecods */ };
示例:
#ifndef __WARP_FUNCTION_H__#define __WARP_FUNCTION_H__#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <pthread.h>#include <sys/socket.h>#ifndef MAXLINE#define MAXLINE 4096#endifvoid err_msg(const char * msg, int error){ printf("%s : %s\n", msg, strerror(error)); exit(1);}int Pthread_create(pthread_t * tid, const pthread_attr_t * attr, void * (*func)(void *), void * arg){ int error = pthread_create(tid, attr, func, arg); if (error != 0) { err_msg("pthread_create error", error); } return(error);}int Pthread_join(pthread_t tid, void ** status){ int error = pthread_join(tid, status); if (error != 0) { err_msg("pthread_join error", error); } return(error);}pthread_t Pthread_self(void){ return(pthread_self());}int Pthread_detach(pthread_t tid){ int error = pthread_detach(tid); if (error != 0) { err_msg("pthread_detach error", error); } return(error);}void Pthread_exit(void * status){ pthread_exit(status);}int Pthread_once(pthread_once_t * onceptr, void (*init)(void)){ int error = pthread_once(onceptr, init); if (error != 0) { err_msg("pthread_once error", error); } return(error);}int Pthread_key_create(pthread_key_t * keyptr, void (*destructor)(void * value)){ int error = pthread_key_create(keyptr, destructor); if (error != 0) { err_msg("pthread_key_create error", error); } return(error);}void * Pthread_getspecific(pthread_key_t key){ return((void *)pthread_getspecific(key));}int Pthread_setspecific(pthread_key_t key, const void * value){ int error = pthread_setspecific(key, value); if (error != 0) { err_msg("pthread_setspecific error", error); } return(error);}int Pthread_mutex_lock(pthread_mutex_t * mptr){ int error = pthread_mutex_lock(mptr); if (error != 0) { err_msg("pthread_mutex_lock error", error); } return(error);}int Pthread_mutex_unlock(pthread_mutex_t * mptr){ int error = pthread_mutex_unlock(mptr); if (error != 0) { err_msg("pthread_mutex_unlock error", error); } return(error);}int Pthread_cond_signal(pthread_cond_t * cptr){ int error = pthread_cond_signal(cptr); if (error != 0) { err_msg("pthread_cond_signal error", error); } return(error);}int Pthread_cond_broadcast(pthread_cond_t * cptr){ int error = pthread_cond_broadcast(cptr); if (error != 0) { err_msg("pthread_cond_broadcast error", error); } return(error);}int Pthread_cond_wait(pthread_cond_t * cptr, pthread_mutex_t * mptr){ int error = pthread_cond_wait(cptr, mptr); if (error != 0) { err_msg("pthread_cond_wait error", error); } return(error);}int Pthread_cond_timedwait(pthread_cond_t * cptr, pthread_mutex_t * mptr, const struct timespec * abstime){ int error = pthread_cond_timedwait(cptr, mptr, abstime); if (error != 0) { err_msg("pthread_cond_timedwait error", error); } return(error);}void * Malloc(size_t size){ void * ptr = malloc(size); if (ptr == NULL) { err_msg("malloc error", errno); } return(ptr);}void * Calloc(size_t nobj, size_t size){ void * ptr = calloc(nobj, size); if (ptr == NULL) { err_msg("calloc error", errno); } return(ptr);}int Socket(int family, int type, int protocol){ int sockfd = socket(family, type, protocol); if (sockfd == -1) { err_msg("socket error", errno); } return(sockfd);}int Connect(int sockfd, const struct sockaddr * servaddr, socklen_t addrlen){ int ret = connect(sockfd, servaddr, addrlen); if (ret == -1) { err_msg("connect error", errno); } return(ret);}int Bind(int sockfd, const struct sockaddr * myaddr, socklen_t addrlen){ int ret = bind(sockfd, myaddr, addrlen); if (ret == -1) { err_msg("bind error", errno); } return(ret);}int Listen(int sockfd, int backlog){ int ret = listen(sockfd, backlog); if (ret == -1) { err_msg("listen error", errno); } return(ret);}int Accept(int sockfd, struct sockaddr * cliaddr, socklen_t * addrlen){ int ret = accept(sockfd, cliaddr, addrlen); if (ret == -1) { err_msg("accept error", errno); } return(ret);}pid_t Fork(void){ int ret = fork(); if (ret == -1) { err_msg("fork error", errno); } return(ret);}int Close(int sockfd){ int ret = close(sockfd); if (ret == -1) { err_msg("close error", errno); } return(ret);}int Shutdown(int sockfd, int howto){ int ret = shutdown(sockfd, howto); if (ret == -1) { err_msg("shutdown error", errno); } return(ret);}int Getsockname(int sockfd, struct sockaddr * localaddr, socklen_t * addrlen){ int ret = getsockname(sockfd, localaddr, addrlen); if (ret == -1) { err_msg("getsockname error", errno); } return(ret);}int Getpeername(int sockfd, struct sockaddr * peeraddr, socklen_t * addrlen){ int ret = getpeername(sockfd, peeraddr, addrlen); if (ret == -1) { err_msg("getpeername error", errno); } return(ret);}#endif
#include "warp.h"#include "tcp_connect.h"static int sockfd; /* global for both threads to access */static FILE * fp;void * copyto(void * arg){ int n; char sendline[MAXLINE]; while (fgets(sendline, MAXLINE, fp) != NULL) { n = strlen(sendline); if (writen(sockfd, sendline, n) != n) { err_msg("writen error", errno); } } if (ferror(fp)) { err_msg("fgets error", errno); } Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */ return(NULL);}void str_cli(FILE * fp_arg, int sockfd_arg){ int n; char recvline[MAXLINE]; pthread_t tid; sockfd = sockfd_arg; /* copy arguments to externals */ fp = fp_arg; Pthread_create(&tid, NULL, copyto, NULL); while ((n = readline(sockfd, recvline, MAXLINE)) > 0) { if (fputs(recvline, stdout) == EOF) { err_msg("fputs error", errno); } } if (n < 0) { err_msg("readline error", errno); }}int main(int argc, char ** argv){ int sockfd; if (argc != 3) { printf("usage: tcpcli <hostname> <service>\n"); exit(1); } sockfd = tcp_connect(argv[1], argv[2]); str_cli(stdin, sockfd); /* do it all */ exit(0);}
#include "warp.h"void * doit(void *arg) /* each thread executes this function */{ int connfd; connfd = *((int *)arg); free(arg); Pthread_detach(Pthread_self()); str_echo(connfd); /* same function as before */ close(connfd); /* done with connected socket */ return(NULL);}int main(int argc, char ** argv){ int listenfd; int * iptr; pthread_t tid; socklen_t addrlen; socklen_t len; struct sockaddr * cliaddr; if (argc == 2) { listenfd = tcp_listen(NULL, argv[1], &addrlen); } else if (argc == 3) { listenfd = tcp_listen(argv[1], argv[2], &addrlen); } else { printf("usage: tcpserv01 [ <host> ] <service or port>\n"); exit(1); } cliaddr = Malloc(addrlen); for ( ; ; ) { len = addrlen; iptr = Malloc(sizeof(int)); *iptr = Accept(listenfd, cliaddr, &len); Pthread_create(&tid, NULL, &doit, iptr); }}
#include "warp.h"static pthread_key_t rl_key;static pthread_once_t rl_once = PTHREAD_ONCE_INIT;void readline_destructor(void * ptr){ free(ptr);}void readline_once(void){ Pthread_key_create(&rl_key, readline_destructor);}typedef struct { int rl_cnt; /* initialize to 0 */ char * rl_bufptr; /* initialize to rl_buf */ char rl_buf[MAXLINE];} Rline;ssize_t my_read(Rline * tsd, int fd, char * ptr){ if (tsd->rl_cnt <= 0) {again: if ((tsd->rl_cnt = read(fd, tsd->rl_buf, MAXLINE)) < 0) { if (errno == EINTR) { goto again; } else { return(-1); } } else if (tsd->rl_cnt == 0) { return(0); } else { tsd->rl_bufptr = tsd->rl_buf; } } tsd->rl_cnt--; *ptr = *tsd->rl_bufptr++; return(1);}ssize_t readline(int fd, void * vptr, size_t maxlen){ size_t n; size_t rc; char c; char * ptr; Rline * tsd; Pthread_once(&rl_once, readline_once); if ((tsd = Pthread_getspecific(rl_key)) == NULL) { tsd = Calloc(1, sizeof(Rline)); /* init to 0 */ Pthread_setspecific(rl_key, tsd); } ptr = vptr; for (n = 1; n < maxlen; n++) { if ((rc = my_read(tsd, fd, &c)) == 1) { *ptr++ = c; if (c == '\n') { break; } } else if (rc == 0) { *ptr = 0; return(n - 1); /* EOF, n - 1 bytes read */ } else { return(-1); /* error, errno set by read() */ } } *ptr = 0; return(n);}ssize_t Readline(int fd, void * ptr, size_t maxlen){ ssize_t n = readline(fd, ptr, maxlen); if (n < 0) { err_msg("readline error", errno); } return(n);}
#include "myio.h"#include "warp.h"#include "tcp_connect.h"#define MAXFILES 20#define SERV "80" /* port number or service name */#define F_CONNECTING 1 /* connect() in progress */#define F_READING 2 /* connect() complete; now reading */#define F_DONE 4 /* all done */#define F_JOINED 8 /* main has pthread_join'ed */#define GET_CMD "GET %s HTTP/1.0\r\n\r\n"#define min(a, b) ((a) < (b) ? (a) : (b))struct file { char * f_name; /* filename */ char * f_host; /* hostname or IP address */ int f_fd; /* descriptor */ int f_flags; /* F_xxx above */ pthread_t f_tid; /* thread ID */} file[MAXFILES];int nconn;int nfiles;int nlefttoconn;int nlefttoread;int ndone; /* number of terminated threads */pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER;void home_page(const char * host, const char * fname){ int fd; int n; char line[MAXLINE]; fd = tcp_connect(host, SERV); /* blocking connect() */ n = snprintf(line, sizeof(line), GET_CMD, fname); if (writen(fd, line, n) != n) { err_msg("writen error", errno); } for ( ; ; ) { if ((n = read(fd, line, MAXLINE)) < 0) { err_msg("read error", errno); } else if (n == 0) { break; /* server closed connection */ } printf("read %d bytes of home page\n", n); /* do whatever with data */ } printf("end-of-file on home page\n"); Close(fd);}void write_get_cmd(struct file * fptr){ int n; char line[MAXLINE]; n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name); if (writen(fptr->f_fd, line, n) != n) { err_msg("writen error", errno); } printf("wrote %d bytes for %s\n", n, fptr->f_name); fptr->f_flags = F_READING; /* clears F_CONNECTING */}void * do_get_read(void * vptr){ int fd; int n; char line[MAXLINE]; struct file * fptr; fptr = (struct file *)vptr; fd = tcp_connect(fptr->f_host, SERV); fptr->f_fd = fd; printf("do_get_read for %s, fd %d, thread %d\n", fptr->f_name, fd, (int)fptr->f_tid); write_get_cmd(fptr); /* write() the GET command */ /* Read server's reply */ for ( ; ; ) { if ((n = read(fd, line, MAXLINE)) < 0) { err_msg("read error", errno); } else if (n == 0) { break; /* server closed connection */ } printf("read %d bytes from %s\n", n, fptr->f_name); } printf("end-of-file on %s\n", fptr->f_name); Close(fd); fptr->f_flags = F_DONE; /* clears F_READING */ Pthread_mutex_lock(&ndone_mutex); ndone++; Pthread_cond_signal(&ndone_cond); Pthread_mutex_unlock(&ndone_mutex); return(fptr); /* terminate thread */}int main(int argc, char ** argv){ int i; int maxnconn; pthread_t tid; struct file * fptr; if (argc < 5) { printf("usage: web <#conns> <IPaddr> <homepage> file1 ...\n"); exit(1); } maxnconn = atoi(argv[1]); nfiles = min(argc - 4, MAXFILES); for (i = 0; i < nfiles; i++) { file[i].f_name = argv[i + 4]; file[i].f_host = argv[2]; file[i].f_flags = 0; } printf("nfiles = %d\n", nfiles); home_page(argv[2], argv[3]); nlefttoread = nlefttoconn = nfiles; nconn = 0; while (nlefttoread > 0) { while (nconn < maxnconn && nlefttoconn > 0) { /* find a file to read */ for (i = 0 ; i < nfiles; i++) { if (file[i].f_flags == 0) { break; } } if (i == nfiles) { printf("nlefttoconn = %d but nothing found\n", nlefttoconn); exit(1); } file[i].f_flags = F_CONNECTING; Pthread_create(&tid, NULL, &do_get_read, &file[i]); file[i].f_tid = tid; nconn++; nlefttoconn--; } /* Wait for thread to terminate */ Pthread_mutex_lock(&ndone_mutex); while (ndone == 0) { Pthread_cond_wait(&ndone_cond, &ndone_mutex); } for (i = 0; i < nfiles; i++) { if (file[i].f_flags & F_DONE) { Pthread_join(file[i].f_tid, (void **) &fptr); if (&file[i] != fptr) { printf("error: file[i] != fptr\n"); exit(1); } fptr->f_flags = F_JOINED; /* clears F_DONE */ ndone--; nconn--; nlefttoread--; printf("thread %d for %s done\n", (int)fptr->f_tid, fptr->f_name); } } Pthread_mutex_unlock(&ndone_mutex); } exit(0);}
- UNP函数笔记十六: 线程
- UNP学习笔记(第二十六章 线程)
- UNP第二十六章 线程
- UNP函数笔记五: 套接字选项
- UNP函数笔记十二: Unix域协议
- UNP函数笔记十四: 带外数据
- unp 笔记
- UNP函数笔记十一: 高级I/O函数
- UNP笔记2——TCP套接口函数
- [UNP笔记]I/O复用,select和poll函数
- UNP函数笔记一: 套接字编程简介
- UNP函数笔记二: 基本TCP套接字编程
- UNP函数笔记三: TCP客户/服务器程序示例
- UNP函数笔记六: 基本UDP套接字编程
- UNP函数笔记七: 基本SCTP套接字编程
- UNP函数笔记八: 名字与地址转换
- UNP函数笔记九: IPv4与IPv6的互操作性
- UNP函数笔记十: 守护进程和inetd超级服务器
- 用cocos2d-x做一个简单的windows phone 7游戏:更猛的怪兽和更多的关卡(三)
- ORA-22285: 对不存在的目录或文件进行 FILEOPEN 操作 ORA-06512: 在 "SYS.DBMS_LOB", line 523 ORA-06512: 在 line 6 查看错误堆
- c语言夜未眠2——实现撤销和重做
- 使用 Windows Server AppFabric 缓存编写 ASP.NET 应用程序
- posix 线程(2)信号量同步
- UNP函数笔记十六: 线程
- 最大值最小化
- matlab坐标轴的设置
- Struts2 自定义拦截器 实现简单权限检查
- 如何使用真机调试Android应用
- struts2 常用迭代判断标签
- 获取桌面路径、应用程序常用存放数据目录
- oracle 复习
- 使用myeclipse自动生成Hibernate文件