为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。

http://www.cnblogs.com/shijiaqi1066/p/5769417.html

线程基础

创建线程

pthread_create

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg);

【参数】

  • tidp:传入函数,该函数会把创建的线程指针赋值给该参数。
  • attr:线程属性。
  • start_rtn:启动线程的函数指针。
  • arg:运行函数的参数。

【返回值】成功,返回0;出错,返回-1。

线程挂起

pthread_join

#include <pthread.h>
int pthread_join( pthread_t thread, void **value_ptr);

让当前线程在等待指定线程执行完后再继续执行。

参数:

  • thread:等待退出线程的线程号。
  • value_ptr:退出线程的返回值。

线程退出

pthread_exit

#include <pthread.h>
void pthread_exit(void *rval_ptr);

退出当前线程。该函数用于线程函数主动退出,而不是让其他线程退出。

获取当前线程id

pthread_self

#include <pthread.h>
pthread_t pthread_self(void);

获取当前线程。线程ID由是pthread_t类型表示。

判断线程是否相等

pthread_equal

#include <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2);

检查两个pthread是否相等。

在不同的系统下,pthread_t的类型是不同的,比如在ubuntn下,是unsigned long类型,而在solaris系统中,是unsigned int类型。而在FreeBSD上才用的是结构题指针。 所以不能直接使用==判读,而应该使用pthread_equal来判断。


例:创建线程

#include <stdio.h>
#include <pthread.h>
#include <unistd.h> // 线程一
void thread_1(void) {
int i = ;
for(i = ; i <= ; i++) {
printf("This is a pthread_1.\n");
if(i == ) {
pthread_exit();
}
sleep();
}
} // 线程二
void thread_2(void) {
int i;
for(i = ; i < ; i++) {
printf("This is a pthread_2.\n");
}
pthread_exit();
} int main(void) {
pthread_t id_1, id_2;
int ret; /*创建线程一*/
ret=pthread_create(&id_1, NULL, (void *) thread_1, NULL);
if(ret != ) {
printf("Create pthread error!\n");
return -;
} /*创建线程二*/
ret=pthread_create(&id_2, NULL, (void *) thread_2, NULL);
if(ret != ) {
printf("Create pthread error!\n");
return -;
} /*等待线程结束*/
pthread_join(id_1, NULL);
pthread_join(id_2, NULL);
return ;
}

线程执行函数的返回值

  • pthread_exit(void *ret)
  • pthread_join(pthread_t id, void **ret)

函数退出时,由pthread_exit函数退出,并用ret传出真正的返回值。外部函数若想接受到该参数,使用pthread_join的第二个参数来接收。

回收线程资源

pthread_detach

#include <pthread.h>
int pthread_detach(pthread_t);

线程分离。

Linux的线程有两种状态:

  • joinable态
  • unjoinable态

默认线程是joinable的,则当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有对该线程调用了pthread_join之后这些资源才会被释放。

线程的unjoinable状态可以在pthread_create时指定,也可以在线程创建后在线程中pthread_detach自己, 确保资源的释放。如:pthread_detach(pthread_self())。

一般的回收线程有两种方法:

方法一:使用pthread_detach让线程自动回收资源。

pthread_t tid;
int status = pthread_create(&tid, NULL, ThreadFunc, NULL);
if(status != ){
perror("pthread_create error");
}
pthread_detach(tid);

方法二:使用thread_join让下一个线程回收当前线程。


互斥量(锁)

创建互斥量

静态初始化互斥量

PTHREAD_MUTEX_INITIALIZER

pthread_mutex_t theMutex;
pthread_mutex_t result = PTHREAD_MUTEX_INITIALIZER;

动态初始化互斥量

pthread_mutex_init

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict_mutex,const pthread_mutextattr_t *restrict attr)

销毁锁

pthread_mutex_destroy

#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);

使用完后释放。

加锁

pthread_mutex_lock

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);

尝试加锁

pthread_mutex_trylock

#include <pthread.h>
int pthread_mutex_trylock( pthread_mutex_t *mutex );

加锁,但是与pthread_mutex_lock不一样的是当锁已经在使用的时候,返回为EBUSY,而不是挂起等待。

在一定时间内加锁

pthread_mutex_timedlock

#include <pthread.h>
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout); 

尝试lock,abs_timeout时间内仍被锁定,返回ETIMEOUT错误。timespec是超时时间,它用秒和纳秒来描述时间。

解锁

pthread_mutex_unlock

#include <pthread.h>
pthread_mutex_unlock(pthread_mutex_t *mutex);

释放锁。

例:两个线程各自加1。

#include <pthread.h>
#include <stdio.h> void add_1(void *arg);
pthread_mutex_t mutex; int main() {
int i = ; // 声明线程
pthread_t thread1,thread2; // 初始化锁
pthread_mutex_init(&mutex,NULL); // 创建线程
int rc1 = pthread_create(&thread1, NULL, (void *)add_1, &i);
if(rc1 != ){
printf("thread-1 create failed: %d\n",rc1);
} // 创建线程
int rc2 = pthread_create(&thread2, NULL, (void *)add_1, &i);
if(rc2 != ){
printf("thread-2 create failed: %d\n",rc1);
} // 等待线程
pthread_join(thread1,NULL);
pthread_join(thread2,NULL); printf("i = %d",i); // 打印输出 i = 210 return ;
} // 线程运行函数
void add_1(void *arg){
int *i = (int *)arg;
for(int n=;n<;n++){
pthread_mutex_lock(&mutex);
(*i)++;
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}

读写互斥量(读写锁)

待写


条件锁

静态创建

PTHREAD_COND_INITIALIZER

#include <pthread.h>
pthread_cond_t my_condition = PTHREAD_COND_INITIALIZER;

动态创建

pthread_cond_init

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

销毁

pthread_cond_destroy

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

等待

pthread_cond_wait

#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

触发

pthread_cond_signal

#include <pthread.h>
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);

例:生产者消费者

main.c

#include <stdio.h>
#include <stdlib.h>
#include "block_queue.h" #define BLOCK_POOL_SIZE 10 void producer(void *arg);
void customer(void *arg); int main() {
int pthread_ret;
pthread_t producer_thread_0,producer_thread_1,customer_thread;
List *plist = block_queue_create(BLOCK_POOL_SIZE); pthread_ret = pthread_create(&producer_thread_0,NULL,(void *)producer,plist);
if(pthread_ret!=){
puts("生产者线程创建失败");
return EXIT_FAILURE;
} pthread_ret = pthread_create(&producer_thread_1,NULL,(void *)producer,plist);
if(pthread_ret!=){
puts("生产者线程创建失败");
return EXIT_FAILURE;
} pthread_ret = pthread_create(&customer_thread,NULL,(void *)customer,plist);
if(pthread_ret!=){
puts("消费者线程创建失败");
return EXIT_FAILURE;
} // 主线程等待.
pthread_join(producer_thread_0,NULL);
pthread_join(producer_thread_1,NULL);
pthread_join(customer_thread,NULL); block_queue_destroy(plist);
return EXIT_SUCCESS;
} void producer(void *arg){
List *plist = (List *)arg;
for (int i = ; i < ; i++) {
block_queue_push(plist,i);
printf("生产数据:%d\n",i);
} printf("---- 生产结束 ----\n");
pthread_exit(NULL);
} void customer(void *arg){
int data;
List *plist = (List *)arg;
for (int i = ; i < ; i++) {
block_queue_pop(plist,&data);
printf("消费数据:%d\n",data);
} printf("---- 消费结束 ----\n");
pthread_exit(NULL);
}

block_queue.h

//
// Created by shijiaqi on 16/11/22.
//
#include <pthread.h> typedef struct list_node{
int data;
struct node *next_node;
} ListNode; typedef struct list{
ListNode *firstNode;
int size;
int full_size;
pthread_mutex_t mutex;
pthread_cond_t cond_for_producer;
pthread_cond_t cond_for_customer;
} List; List * block_queue_create(int full_size); void block_queue_destroy(List *plist); void block_queue_push(List *plist,int data); int block_queue_pop(List *plist,int *p_data);

block_queue.c

//
// Created by shijiaqi on 16/11/22.
//
#include "block_queue.h"
#include <stdlib.h>
#include <stdio.h> List * block_queue_create(int full_size){
// 分配内存
List *plist = malloc(sizeof(List));
plist->full_size = full_size;
plist->size = ;
plist->firstNode = NULL; // 初始化锁与条件等待.
pthread_mutex_init(&(plist->mutex),NULL);
pthread_cond_init(&(plist->cond_for_customer),NULL);
pthread_cond_init(&(plist->cond_for_producer),NULL); return plist;
} void block_queue_destroy(List *plist){
int data = ;
int ret = ; // 销毁所有数据。
while(ret==){
if(plist->size > ) {
ret = block_queue_pop(plist, &data);
}else{
break ;
}
} // 销毁锁与条件等待
pthread_cond_destroy(&(plist->cond_for_producer));
pthread_cond_destroy(&(plist->cond_for_customer));
pthread_mutex_destroy(&(plist->mutex)); // 释放内存
free(plist);
} void block_queue_push(List *plist,int data) {
// lock
pthread_mutex_lock(&(plist->mutex)); while(plist->size>=plist->full_size){
printf("队列已满,生产者阻塞。目前仓储数量:%d\n",plist->size);
pthread_cond_wait(&(plist->cond_for_producer),&(plist->mutex));
} ListNode *curNode = plist->firstNode;
if(curNode == NULL) {
ListNode *new_node = malloc(sizeof(ListNode));
new_node->next_node = NULL;
new_node->data = data;
plist->firstNode = new_node;
plist->size++; printf("队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:%d\n",plist->size);
pthread_cond_signal(&(plist->cond_for_customer)); // unlock
pthread_mutex_unlock(&(plist->mutex));
return ;
} ListNode *lastNode = curNode;
curNode = (ListNode *)curNode->next_node;
for(;;){
if(curNode==NULL) {
curNode = malloc(sizeof(ListNode));
curNode->next_node = NULL;
curNode->data = data;
lastNode->next_node = (struct node *)curNode;
plist->size++; printf("队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:%d\n",plist->size);
pthread_cond_signal(&(plist->cond_for_customer)); // unlock
pthread_mutex_unlock(&(plist->mutex));
return ;
}
lastNode = curNode;
curNode = (ListNode *)curNode->next_node;
}
} int block_queue_pop(List *plist,int *p_data) {
// lock
pthread_mutex_lock(&(plist->mutex));
while(plist->size <= ){
printf("队列已空,消费者阻塞。目前仓储数量:%d\n",plist->size);
pthread_cond_wait(&(plist->cond_for_customer),&(plist->mutex));
} ListNode *curNode = plist->firstNode;
if(curNode == NULL){
printf("队列为空,通知阻塞的生产者。目前仓储数量:%d\n",plist->size);
pthread_cond_signal(&(plist->cond_for_producer));
// unlock
pthread_mutex_unlock(&(plist->mutex));
return ; // no data
} else {
*p_data = curNode->data;
plist->firstNode = (ListNode *)curNode->next_node;
free(curNode);
plist->size--; printf("队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:%d\n",plist->size);
pthread_cond_signal(&(plist->cond_for_producer)); // unlock
pthread_mutex_unlock(&(plist->mutex));
return ;
}
}

打印输出:

队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:1
生产数据:0
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:2
生产数据:0
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:1
消费数据:0
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:2
生产数据:1
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:3
生产数据:1
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:2
消费数据:0
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:3
生产数据:2
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:4
生产数据:2
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:3
消费数据:1
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:4
生产数据:3
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:5
生产数据:3
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:4
消费数据:1
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:5
生产数据:4
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:6
生产数据:4
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:5
消费数据:2
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:6
生产数据:5
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:7
生产数据:5
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:6
消费数据:2
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:7
生产数据:6
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:8
生产数据:6
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:7
消费数据:3
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:8
生产数据:7
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:9
生产数据:7
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:8
消费数据:3
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:9
生产数据:8
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:8
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:4
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:9
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:4
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:5
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:9
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:5
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:6
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:11
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:6
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:12
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:7
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:11
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:7
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:12
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:8
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:13
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:8
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:14
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:9
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:13
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:10
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:14
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:9
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:15
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:10
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:16
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:11
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:15
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:12
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:16
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:11
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:17
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:12
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:18
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:13
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:17
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:14
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:18
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:13
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:19
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:14
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:20
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:15
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:19
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:16
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:20
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:15
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:21
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:16
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:22
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:17
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:23
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:18
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:24
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:17
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:21
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:18
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:22
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:19
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:25
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:20
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:26
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:19
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:23
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:20
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:24
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:21
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:27
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:22
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:28
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:23
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:25
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:24
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:26
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:21
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:29
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:22
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:30
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:25
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:27
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:26
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:28
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:23
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:31
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:24
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:32
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:27
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:29
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:28
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:30
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:25
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:33
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:26
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:34
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:29
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:31
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:30
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:32
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:27
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:35
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:28
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:36
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:31
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:33
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:32
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:34
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:29
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:35
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:30
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:36
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:33
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:37
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:34
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:38
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:31
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:37
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:32
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:38
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:35
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:10
生产数据:39
---- 生产结束 ----
队列已满,生产者阻塞。目前仓储数量:10
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:9
消费数据:36
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:8
消费数据:33
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:7
消费数据:34
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:6
消费数据:35
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:5
消费数据:36
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:4
消费数据:37
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:3
消费数据:38
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:2
消费数据:37
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:1
消费数据:38
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:0
消费数据:39
队列刚才生产一条数据,通知阻塞的消费者。目前仓储数量:1
生产数据:39
---- 生产结束 ----
队列被消费了一条数据,通知阻塞的生产者。目前仓储数量:0
消费数据:39
---- 消费结束 ----

例:实现线程的sleep函数。Linux是无法直接使线程sleep的,所以需要使用 pthread_cond_timedwait() 函数实现线程的sleep函数。

以下实现性能可能有问题,因为需要重复初始化/销毁互斥量与等待条件量。这里主要是要给出pthread_cond_timedwait使用方法与简单实现sleep函数。

main.c

#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include "pthread_sleep.h" void test_loop(); int main() {
pthread_t thread;
pthread_create(&thread,NULL,(void *)test_loop,NULL);
pthread_join(thread,NULL);
return ;
} void test_loop() {
time_t now; for(;;){
pthread_sleep();
time(&now);
printf("%s",asctime(gmtime(&now)));
}
}

pthread_sleep.h

#ifndef C_POINTER_PTHREAD_SLEEP_H
#define C_POINTER_PTHREAD_SLEEP_H #endif //C_POINTER_PTHREAD_SLEEP_H unsigned int pthread_sleep(unsigned int seconds);

pthread_sleep.c

#include <pthread.h>
#include <sys/time.h>
#include "pthread_sleep.h" unsigned int pthread_sleep(unsigned int seconds) {
pthread_cond_t cond;
pthread_mutex_t mutex; // 创建锁
pthread_cond_init(&cond,NULL);
pthread_mutex_init(&mutex,NULL); // 时间计算。此处计算的是,等待的截止时间。即当前时刻到达这个时间点,线程就不再被阻塞。
struct timeval now;
gettimeofday(&now, NULL);
struct timespec sleep_time = {now.tv_sec + seconds,}; // 加锁
pthread_mutex_lock(&mutex); // 等待。等到到指定时间,继续执行。
pthread_cond_timedwait(&cond,&mutex,&sleep_time); // 解锁
pthread_mutex_unlock(&mutex); // 销毁
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex); return ;
}

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。

http://www.cnblogs.com/shijiaqi1066/p/5769417.html

Linux C —— 多线程的更多相关文章

  1. [转]Linux 的多线程编程的高效开发经验

    Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...

  2. 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)   介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...

  3. Linux 的多线程编程的高效开发经验(转)

    http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/ 背景 Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多 ...

  4. Linux 的多线程编程的高效开发经验

    http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/ 背景 Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多 ...

  5. Linux C 多线程

    原文:Linux C 多线程 linux下C语言多线程编程 #include <pthread.h> #include <stdio.h> #include <sys/t ...

  6. Linux下多线程编程遇到的一些问题

    今天在学习了Linux的多线程编程的基础的知识点.于是就试着做了一个简单的Demo.本以为会得到预期的结果.不成想却遇到了意想不到的问题. 代码展示 我的C 代码很简单,就是一个简单的示例程序,如下: ...

  7. [转载]解决linux 下多线程错误 undefined reference to `sem_init'

    转自:https://blog.csdn.net/yzycqu/article/details/7396498?utm_source=copy 解决linux 下多线程错误 undefined ref ...

  8. linux C 多线程/线程池编程 同步实例

    在多线程.线程池编程中经常会遇到同步的问题. 1.创建线程 函数原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, ...

  9. Linux内核多线程实现方法 —— kthread_create函数【转】

    转自:http://blog.csdn.net/sharecode/article/details/40076951 Linux内核多线程实现方法 —— kthread_create函数 内核经常需要 ...

  10. Linux中多线程信号的处理

    1. 博文:Linux多线程中使用信号-1  http://blog.csdn.net/qq276592716/article/details/7325250 2. 博文:Linux多线程信号总结  ...

随机推荐

  1. BZOJ_1612_[Usaco2008_Jan]_Cow_Contest_奶牛的比赛_(dfs)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1612 \(n\)头奶牛比赛,给出一些胜负情况,问可以确定多少头奶牛的排名. 分析 无论胜负,只 ...

  2. Linux kernel AACRAID Driver Compat IOCTL 本地安全绕过漏洞

    漏洞名称: Linux kernel AACRAID Driver Compat IOCTL 本地安全绕过漏洞 CNNVD编号: CNNVD-201311-390 发布时间: 2013-11-29 更 ...

  3. 物联网操作系统HelloX V1.77(beta)版本发布

    物联网操作系统HelloX V1.77发布 经过近半年的努力,物联网操作系统HelloX V1.77版本正式完成,源代码已上载到github(github.com/hellox-project/Hel ...

  4. noip 2014 子矩阵

    先枚举行再DP列.好题,详见代码 #include <cstdio> #include <cstring> #include <cstdlib> #include ...

  5. Esper系列(九)NamedWindow语法create、Insert、select

    功能:用于存储一种或多种类型的事件的集合,并能对所存储的事件进行增删改查操作. CreateNameWindow 根据已有的数据源构造 格式: 1  [context context_name]  2 ...

  6. 8-14-Exercise(博弈:HDU 1846 & HDU 1527 )

    B.HDU 1846    Brave Game 算是最简单的入门博弈题吧...... 呃......我用的......算是不是方法的方法吧——找规律~ 可以发现:X-M为奇数时,先手会输:而为偶数的 ...

  7. weapon制作武器

    weapon制作武器 (weapon.pas/c/cpp) 解题报告 制作武器weapon.pas/c/cpp) 背景 WZland的紧急避难所很快就建好了,WZland的居民们陆续地来到这个紧急避难 ...

  8. elasticsearch的基本用法

    开始学习使用 elasticsearch, 把步骤记录在这里: 最大的特点: 1. 数据库的 database, 就是  index 2. 数据库的 table,  就是 tag 3. 不要使用bro ...

  9. Python 学习入门(28)—— 服务器实例

    在新的Python 3.x中,BaseHTTPServer, SimpleHTTPServer, CGIHTTPServer整合到http.server包,SocketServer改名为sockets ...

  10. $.post()请求 ation请求,jsp获取的处理结果

    public void write(String content, String charset) { getHttpResponse().setCharacterEncoding(charset); ...