zoukankan      html  css  js  c++  java
  • APUE 线程

    APUE 线程 - 程序清单


    程序清单11-1 打印线程ID
    #include "util.h"
    #include<pthread.h>
    
    pthread_t ntid;
    
    void
    printids(const char *s)
    {
    	pid_t		pid;
    	pthread_t	tid;
    
    	pid = getpid();
    	tid = pthread_self();
    	//之所以打印16进制,便于pthread_t是结构体的话看地址;
    	printf("%s pid %u tid %u (0x%x)
    ", s, (unsigned int)pid,
    	  (unsigned int)tid, (unsigned int)tid);
    }
    
    void *
    thr_fn(void *arg)
    {
    	printids("new thread: ");
    	return((void *)0);
    }
    
    int
    main(void)
    {
    	int		err;
    
    	err = pthread_create(&ntid, NULL, thr_fn, NULL);
    	if (err != 0)
    		err_quit("can't create thread: %s
    ", strerror(err));
    	printids("main thread:");
    	sleep(1);//确保会运行新线程
    	exit(0);
    }



    程序清单11-2  获得线程退出状态
    #include "util.h"
    #include <pthread.h>
    
    void *
    thr_fn1(void *arg)
    {
    	printf("thread 1 returning
    ");
    	return((void *)1);
    }
    
    void *
    thr_fn2(void *arg)
    {
    	printf("thread 2 exiting
    ");
    	pthread_exit((void *)2);
    }
    
    int
    main(void)
    {
    	int			err;
    	pthread_t	tid1, tid2;
    	void		*tret;
    
    	err = pthread_create(&tid1, NULL, thr_fn1, NULL);
    	if (err != 0)
    		err_quit("can't create thread 1: %s
    ", strerror(err));
    	err = pthread_create(&tid2, NULL, thr_fn2, NULL);
    	if (err != 0)
    		err_quit("can't create thread 2: %s
    ", strerror(err));
    	err = pthread_join(tid1, &tret);
    	if (err != 0)
    		err_quit("can't join with thread 1: %s
    ", strerror(err));
    	printf("thread 1 exit code %d
    ", (int)tret);
    	err = pthread_join(tid2, &tret);
    	if (err != 0)
    		err_quit("can't join with thread 2: %s
    ", strerror(err));
    	printf("thread 2 exit code %d
    ", (int)tret);
    																											exit(0);
    }



    程序清单11-3  pthread_exit 的參数不对使用
    #include "util.h"
    #include <pthread.h>
    
    struct foo {
    	int a, b, c, d;
    };
    
    void
    printfoo(const char *s, const struct foo *fp)
    {
    	printf(s);
    	printf("  structure at 0x%x
    ", (unsigned)fp);
    	printf("  foo.a = %d
    ", fp->a);
    	printf("  foo.b = %d
    ", fp->b);
    	printf("  foo.c = %d
    ", fp->c);
    	printf("  foo.d = %d
    ", fp->d);
    }
    
    void *
    thr_fn1(void *arg)
    {
    	struct foo	foo = {1, 2, 3, 4};
    
    	printfoo("thread 1:
    ", &foo);
    	pthread_exit((void *)&foo);
    	//这里是自己主动变量。退出的时候仅仅是告知监听者退出状态码所在的地址。可是里面的内容在函数退出时就变了;
    }
    
    void *
    thr_fn2(void *arg)
    {
    	printf("thread 2: ID is %ld
    ", pthread_self());//这里最好用长整型;
    	pthread_exit((void *)0);
    }
    
    int
    main(void)
    {
    	int			err;
    	pthread_t	tid1, tid2;
    	struct foo	*fp;
    
    	err = pthread_create(&tid1, NULL, thr_fn1, NULL);
    	if (err != 0)
    		err_quit("can't create thread 1: %s
    ", strerror(err));
    	err = pthread_join(tid1, (void *)&fp);
    	if (err != 0)
    		err_quit("can't join with thread 1: %s
    ", strerror(err));
    	sleep(1);
    	printf("parent starting second thread
    ");
    	err = pthread_create(&tid2, NULL, thr_fn2, NULL);
    	if (err != 0)
    		err_quit("can't create thread 2: %s
    ", strerror(err));
    	sleep(1);
    	printfoo("parent:
    ", fp);
    	exit(0);
    }



    程序清单11-4  线程清理处理程序
    #include "util.h"
    #include <pthread.h>
    
    void
    cleanup(void *arg)
    {
    	printf("cleanup: %s
    ", (char *)arg);
    }
    
    void *
    thr_fn1(void *arg)
    {
    	printf("thread 1 start
    ");
    	pthread_cleanup_push(cleanup, "thread 1 first handler");
    	pthread_cleanup_push(cleanup, "thread 1 second handler");
    	printf("thread 1 push complete
    ");
    	if (arg)
    		return((void *)1);
    	//假设从启动例程中返回而终止不会调用清理函数。
    	pthread_cleanup_pop(0);
    	pthread_cleanup_pop(0);
    	return((void *)1);
    }
    
    void *
    thr_fn2(void *arg)
    {
    	printf("thread 2 start
    ");
    	pthread_cleanup_push(cleanup, "thread 2 first handler");
    	pthread_cleanup_push(cleanup, "thread 2 second handler");
    	printf("thread 2 push complete
    ");
    	if (arg)
    		pthread_exit((void *)2);
    	pthread_cleanup_pop(0);
    	pthread_cleanup_pop(0);
    	pthread_exit((void *)2);
    }
    
    int
    main(void)
    {
    	int			err;
    	pthread_t	tid1, tid2;
    	void		*tret;
    
    	err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);
    	if (err != 0)
    		err_quit("can't create thread 1: %s
    ", strerror(err));
    	err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);
    	if (err != 0)
    		err_quit("can't create thread 2: %s
    ", strerror(err));
    	err = pthread_join(tid1, &tret);
    	if (err != 0)
    		err_quit("can't join with thread 1: %s
    ", strerror(err));
    	printf("thread 1 exit code %d
    ", (int)tret);
    	err = pthread_join(tid2, &tret);
    	if (err != 0)
    		err_quit("can't join with thread 2: %s
    ", strerror(err));
    	printf("thread 2 exit code %d
    ", (int)tret);
    	exit(0);
    }



    程序清单11-5  使用相互排斥量保护数据结构
    #include <stdlib.h>
    #include <stdio.h>
    #include <pthread.h>
    
    struct foo {
    	int             f_count;
    	pthread_mutex_t f_lock;
    	/* ... more stuff here ... */
    };
    
    struct foo *
    foo_alloc(void) /* allocate the object */
    {
    	struct foo *fp;
    
    	if ((fp = malloc(sizeof(struct foo))) != NULL) {
    		fp->f_count = 1;
    		if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
    			free(fp);
    			return(NULL);
    		}
    		/* ... continue initialization ... */
    	}
    	return(fp);
    }
    
    void
    foo_hold(struct foo *fp) /* add a reference to the object */
    {
    	pthread_mutex_lock(&fp->f_lock);
    	fp->f_count++;
    	pthread_mutex_unlock(&fp->f_lock);
    }
    
    void
    foo_rele(struct foo *fp) /* release a reference to the object */
    {
    	pthread_mutex_lock(&fp->f_lock);
    	if (--fp->f_count == 0) { /* last reference */
    		pthread_mutex_unlock(&fp->f_lock);
    		pthread_mutex_destroy(&fp->f_lock);
    		free(fp);
    	} else {
    		pthread_mutex_unlock(&fp->f_lock);
    	}
    }
    
    void *thr_fn1(void *pp){
    	struct foo *p=(struct foo *)pp;
    	printf("thread 1.......
    ");
    	foo_hold(p);
    	pthread_exit((void*)1);
    }
    void *thr_fn2(void *pp){
    	struct foo *p=(struct foo *)pp;
            printf("thread 2.......
    ");
            foo_hold(p);
            pthread_exit((void*)2);
    }
    int 
    main(){
    	pthread_t tid1,tid2;
    	void * ret1,*ret2;
    	struct foo *pf;
    	pf = foo_alloc();
    	if(!pf)
    		exit(-1);
    	pthread_create(&tid1,NULL,thr_fn1,(void *)pf);
    	
    	pthread_join(tid1,&ret1);
    	printf("main 1 : %d --
    ",pf->f_count);
    	pthread_create(&tid2,NULL,thr_fn2,(void *)pf);
    	printf("main 2 : %d --
    ",pf->f_count);
    
    	pthread_join(tid2,&ret2);
    	printf("main 3 : %d --
    ",pf->f_count);
    
    }
    


    程序清单11-6  使用两个相互排斥量
    #include <stdlib.h>
    #include <pthread.h>
    
    #define NHASH 29
    #define HASH(fp) (((unsigned long)fp)%NHASH)
    
    struct foo *fh[NHASH];
    
    pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;
    
    struct foo {
    	int             f_count;
    	pthread_mutex_t f_lock;
    	struct foo     *f_next; /* protected by hashlock */
    	int             f_id;
    	/* ... more stuff here ... */
    };
    
    struct foo *
    foo_alloc(void) /* allocate the object */
    {
    	struct foo	*fp;
    	int			idx;
    	if ((fp = malloc(sizeof(struct foo))) != NULL) {
    		fp->f_count = 1;
    		if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
    			free(fp);
    			return(NULL);
    		}
    		idx = HASH(fp);
    		pthread_mutex_lock(&hashlock);
    		fp->f_next = fh[idx];
    		fh[idx] = fp->f_next;
    		pthread_mutex_lock(&fp->f_lock);
    		pthread_mutex_unlock(&hashlock);
    		/* ... continue initialization ... */
    		thread_mutex_unlock(&fp->f_lock);
    		}
    		return(fp);
    }
    
    void
    foo_hold(struct foo *fp) /* add a reference to the object */
    {
    	pthread_mutex_lock(&fp->f_lock);
    	fp->f_count++;
    	pthread_mutex_unlock(&fp->f_lock);
    }
    
    struct foo *
    foo_find(int id) /* find an existing object */
    {
    	struct foo	*fp;
    	int			idx;
    
    	idx = HASH(fp);
    	pthread_mutex_lock(&hashlock);
    	for (fp = fh[idx]; fp != NULL; fp = fp->f_next) {
    		if (fp->f_id == id) {
    			foo_hold(fp);
    			break;
    		}
    	}
    	pthread_mutex_unlock(&hashlock);
    	return(fp);
    }
    
    void
    foo_rele(struct foo *fp) /* release a reference to the object */
    {
    	struct foo	*tfp;
    	int			idx;
    
    	pthread_mutex_lock(&fp->f_lock);
    	if (fp->f_count == 1) { /* last reference */
    		pthread_mutex_unlock(&fp->f_lock);
    		pthread_mutex_lock(&hashlock);
    		pthread_mutex_lock(&fp->f_lock);
    		/* need to recheck the condition */
    		if (fp->f_count != 1) {
    			fp->f_count--;
    			pthread_mutex_unlock(&fp->f_lock);
    			pthread_mutex_unlock(&hashlock);
    			return;
    		}
    		/* remove from list */
    		idx = HASH(fp);
    		tfp = fh[idx];
    		if (tfp == fp) {
    			fh[idx] = fp->f_next;
    		} else {
    			while (tfp->f_next != fp)
    			tfp = tfp->f_next;
    			tfp->f_next = fp->f_next;
    		}
    		pthread_mutex_unlock(&hashlock);
    		pthread_mutex_unlock(&fp->f_lock);
    		pthread_mutex_destroy(&fp->f_lock);
    		free(fp);
    		} else {
    			fp->f_count--;
    			pthread_mutex_unlock(&fp->f_lock);
    		}
    }



    程序清单11-7  简化的加,解锁
    #include <stdlib.h>
    #include <pthread.h>
    
    #define NHASH 29
    #define HASH(fp) (((unsigned long)fp)%NHASH)
    
    struct foo *fh[NHASH];
    pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;
    
    struct foo {
      int f_count;                  /* protected by hashlock */
      pthread_mutex_t f_lock;
      struct foo *f_next;           /* protected by hashlock */
      int f_id;
      /* ... more stuff here ... */
    };
    
    struct foo *
    foo_alloc(void)                 /* allocate the object */
    {
      struct foo *fp;
      int idx;
    
      if ((fp = malloc(sizeof(struct foo))) != NULL) {
        fp->f_count = 1;
        if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
          free(fp);
          return NULL;
        }
        idx = HASH(fp);
        pthread_mutex_lock(&hashlock);
        fp->f_next = fh[idx];
        fh[idx] = fp;
        pthread_mutex_lock(&fp->f_lock); // Why ?

    ?? pthread_mutex_unlock(&hashlock); /* ... continue initialization ... */ } return fp; } void foo_hold(struct foo *fp) /* add a reference to the object */ { pthread_mutex_lock(&hashlock); fp->f_count++; pthread_mutex_unlock(&hashlock); } struct foo * foo_find(int id) /* find an existing object */ { struct foo *fp; int idx; idx = HASH(fp); pthread_mutex_lock(&hashlock); for (fp = fh[idx]; fp != NULL; fp = fp->f_next) { if (fp->f_id == id) { fp->f_count++; break; } } pthread_mutex_unlock(&hashlock); return fp; } void foo_rele(struct foo *fp) /* release a reference to the object */ { struct foo *tfp; int idx; pthread_mutex_lock(&hashlock); if (--fp->f_count == 0) { /* last reference, remove from list */ idx = HASH(fp); tfp = fh[idx]; if (tfp == fp) { fh[idx] = fp->f_next; } else { while (tfp->f_next != fp) tfp = tfp->f_next; tfp->f_next = fp->f_next; } pthread_mutex_unlock(&hashlock); pthread_mutex_destroy(&fp->f_lock); free(fp); } else { pthread_mutex_unlock(&hashlock); } }



    程序清单11-8  使用读写锁
    #include <stdlib.h>
    #include <pthread.h>
    
    struct job {
      struct job *j_next;
      struct job *j_prev;
      pthread_t j_id;               /* tells which thread handles this job */
      /* ... more stuff here ... */
    };
    
    struct queue {
      struct job *q_head;
      struct job *q_tail;
      pthread_rwlock_t q_lock;
    };
    
    /*
     * Initialize a queue.
     */
    int
    queue_init(struct queue *qp)
    {
      int err;
    
      qp->q_head = NULL;
      qp->q_tail = NULL;
      err = pthread_rwlock_init(&qp->q_lock, NULL);
      if (err != 0)
        return err;
    
      /* ... continue initialization ... */
    
      return 0;
    }
    
    /*
     * Insert a job at the head of the queue.
     */
    void
    job_insert(struct queue *qp, struct job *jp)
    {
      pthread_rwlock_wrlock(&qp->q_lock);
      jp->j_next = qp->q_head;
      jp->j_prev = NULL;
      if (qp->q_head != NULL)
        qp->q_head->j_prev = jp;
      else
        qp->q_tail = jp;            /* list was empty */
      qp->q_head = jp;
      pthread_rwlock_unlock(&qp->q_lock);
    }
    
    /*
     * Append a job on the tail of the queue.
     */
    void
    job_append(struct queue *qp, struct job *jp)
    {
      pthread_rwlock_wrlock(&qp->q_lock);
      jp->j_next = NULL;
      jp->j_prev = qp->q_tail;
      if (qp->q_tail != NULL)
        qp->q_tail->j_next = jp;
      else
        qp->q_head = jp;            /* list was empty */
      qp->q_tail = jp;
      pthread_rwlock_unlock(&qp->q_lock);
    }
    
    /*
     * Remove the given job from a queue.
     */
    void
    job_remove(struct queue *qp, struct job *jp)
    {
      pthread_rwlock_wrlock(&qp->q_lock);
      if (jp == qp->q_head) {
        qp->q_head = jp->j_next;
        if (qp->q_tail == jp)
          qp->q_tail = NULL;
      } else if (jp == qp->q_tail) {
        qp->q_tail = jp->j_prev;
        if (qp->q_head == jp)
          qp->q_head = NULL;
      } else {
        jp->j_prev->j_next = jp->j_next;
        jp->j_next->j_prev = jp->j_prev;
      }
      pthread_rwlock_unlock(&qp->q_lock);
    }
    
    /*
     * Find a job for the given thread ID.
     */
    struct job *
    job_find(struct queue *qp, pthread_t id)
    {
      struct job *jp;
    
      if (pthread_rwlock_rdlock(&qp->q_lock) != 0)
        return NULL;
    
      for (jp = qp->q_head; jp != NULL; jp = jp->j_next)
        if (pthread_equal(jp->j_id, id))
          break;
    
      pthread_rwlock_unlock(&qp->q_lock);
      return jp;
    }


    程序清单11-9  使用条件变量

    #include <pthread.h>
    
    struct msg {
      struct msg *m_next;
      /* ... more stuff ... */
    };
    
    struct msg *workq;
    pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
    
    void
    process_msg(void)
    {
      struct msg *mp;
    
      for (;;) {
        pthread_mutex_lock(&qlock);
        while (workq == NULL)
          pthread_cond_wait(&qready, &qlock);
        mp = workq;
        workq = mp->m_next;
        pthread_mutex_unlock(&qlock);
        /* now process the message mp */
      }
    }
    
    void
    enqueue_msg(struct msg *mp)
    {
      pthread_mutex_lock(&qlock);
      mp->m_next = workq;
      workq = mp;
      pthread_mutex_unlock(&qlock);
      pthread_cond_signal(&qready);
    }




  • 相关阅读:
    箭头函数1
    变量结构赋值
    警惕32位程序在MethodImplOptions.Synchronized在x64机器上的同步缺陷[z]
    ListView的BeginUpdate()和EndUpdate()作用[z]
    如何用命令将本地项目上传到git[z]
    C# 两个datatable中的数据快速比较返回交集或差集[z]
    C# DataTable抽取Distinct数据(不重复数据)[z]
    【Thread】CountdownEvent任务并行[z]
    C#多线程--信号量(Semaphore)[z]
    VS2015一新建项目就出现未将对象引用设置到对象的实例怎么办?[z]
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7205443.html
Copyright © 2011-2022 走看看