线程

Posix线程

#include <pthread.h>
    int pthread_create(&tid, &attr, func, args);      //线程ID, 属性(优先级,守护线程), 函数,参数
            (void *)(* func)(void *)  // void *可以传任何参数,返回任何值
            0: 成功   错误时不设置errno, 返回正值Exxx, EAGAIN。。。
    int pthread_join(tid, &pState)  
           // 等待线程tid结束,并将状态返回(二级指针)。0:成功,同上
           // 不像进程可以等待任意子进程结束
    pthread_t pthread_self()        
          // 线程tid为无符号整数
    int pthread_detach(tid)   
         //可汇合的线程,结束时保留状态;分离的线程,结束时资源全部释放
         //被想脱离自己的线程调用。  
    void pthread_exit(&status)
        //线程终止


 互斥锁:

    阻止对共享变量的同时访问   // 545/873     pthread_mutex_t (mutual exclusion)     

    pthread_mutex_t  lock = PTHREAD_MUTEX_INITIALIZER 
    pthread_mutex_init        //用共享内存分配的锁,用此函数初始化  
    pthread_mutex_lock(&lock);
    local_var = g_counter;    // A :  两个线程都操作这3行,某个线程在A或者B点,切换到另一个线程去一直执行,
     printf("%d: %d", tid, local_var + 1);  // B :  再切换回来,A的local_var还是原来的值,加1后覆盖g_counter,出现错误!
    g_counter = local_var + 1;
    pthread_mutex_unlock(&lock)   

条件变量:

    睡眠等待某种条件出现    //  549/873   pthread_cond_t 

   int pthread_cond_wait(*condi, *mutex)  // A线程在等待条件M
   int pthread_cond_signal(*condi)        // B线程通知一个等待条件M的线程   
   int pthread_cond_timedwait(条件,锁,绝对时间)
   int pthread_cond_broadcast(*condi)     //  通知所有


线程与进程的区别 

进程fork的问题:
    1. 昂贵。虽然用了写时拷贝技术,但内存映像,描述字要拷贝到子进程。
    2. 通信。父子进程通信不方便,虽然有IPC通信。
线程:
    1. 创建一般快10-100倍
    2. 进程内的线程共享资源(进程指令,打开的文件,信号处理,工作目录,用户ID和组ID),除了ID,寄存器,栈,信号掩码,优先级,errno
    3. 引入了同步问题。 func_r 为线程安全的函数,即无全局或者静态变量(线程共享不安全)。
    4. 线程函数的参数为 void *, 将int 转成它,只有在整数大小 <= 指针大小 的系统上该强转才工作。
   若 &connId, 则因为线程间共享,所以不安全。
   若 pConnId, 每个线程新分配一个,但malloc , free , 是不可重入的函数(有静态变量)。
区别: 总之:线程共享,进程复制
     在用子进程或者线程处理服务器监听收到客户端请求,即accept后的处理
              父进程需要关闭accept的连接;线程不能关(共享,关了后,生成的线程无法处理)
              生成线程中处理完后关闭客户端的连接;子进程不必关(子进程结束后,其连接自动关了)

 

 

例子:

pthread_cond_wait(&products->notFull, &products->locker);    // 等

pthread_cond_signal(&products->notFull);                                   // 通知

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define BUFFER_SIZE 8
#define END_FLAG (-1)

struct Products
{
int buffer[BUFFER_SIZE];
pthread_mutex_t locker;           //保证存取操作的原子性 互斥性
pthread_cond_t notEmpty;          //是否可读       
pthread_cond_t notFull;           //是否可写
int posReadFrom;
int posWriteTo;
};

int BufferIsFull(struct Products* products)
{
if ((products->posWriteTo + 1) % BUFFER_SIZE == products->posReadFrom)
{
return (1);
}
return (0);
}


int BufferIsEmpty(struct Products* products)
{
if (products->posWriteTo == products->posReadFrom)
{
return (1);
}
return (0);
}

//制造产品。
void Produce(struct Products* products, int item)
{
pthread_mutex_lock(&products->locker); 
 //无空间可写入
while (BufferIsFull(products))
{
	pthread_cond_wait(&products->notFull, &products->locker);
} 
//写入数据
products->buffer[products->posWriteTo] = item;
products->posWriteTo++;
if (products->posWriteTo >= BUFFER_SIZE)
	products->posWriteTo = 0;
// 通知不空,可读了
pthread_cond_signal(&products->notEmpty);     
//解锁
pthread_mutex_unlock(&products->locker);      
}


int Consume(struct Products* products)
{
int item;

pthread_mutex_lock(&products->locker);

while (BufferIsEmpty(products))
{
	pthread_cond_wait(&products->notEmpty, &products->locker);
} //为空时持续等待,无数据可读
//提取数据
item = products->buffer[products->posReadFrom];
products->posReadFrom++;
if (products->posReadFrom >= BUFFER_SIZE) //如果到末尾,从头读取
	products->posReadFrom = 0;
pthread_cond_signal(&products->notFull); 

pthread_mutex_unlock(&products->locker);

return item;
}


struct Products products;

void* ProducerThread(void* data)
{
int i;
for (i = 0; i < 16; ++i)
{
printf("producer: %d\n", i);
Produce(&products, i);
}
Produce(&products, END_FLAG);
return NULL;
}


void* ConsumerThread(void* data)
{
int item;

while (1)
{
item = Consume(&products);
if (END_FLAG == item)
       break;
printf("consumer: %d\n", item);
}
return (NULL);
}


int main(int argc, char* argv[])
{
pthread_t producer;
pthread_t consumer;
int result;

pthread_create(&producer, NULL, &ProducerThread, NULL);
pthread_create(&consumer, NULL, &ConsumerThread, NULL);

pthread_join(producer, (void *)&result);
pthread_join(consumer, (void *)&result);

exit(EXIT_SUCCESS);
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值