11.21学习笔记-线程

一、网络编程部分:

遇到的各种函数:

1、exec()函数

    exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件

2、线程

  • 什么是线程?线程是进程的一个执行流,一个进程由几个线程组成。线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉。线程创建的时间更快更容易是因为它不用分配地址空间吗?
  • 什么是线程ID?首先它是由系统分配的。线程ID是操作系统识别线程的唯一标志。和进程一样,每个开启的线程都由系统分配一个唯一的编号于其它线程相区别,是一个长整型的数字。
  •    多线程是异部通信,没有先后顺序。
  • 线程操作的相关函数
    #include <pthread.h>//创建线程的头函数吧
     
    int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg);
    //pthread_create用于创建一个线程,如果成功返回0,失败返回Exxx.pthread_t指的是线程ID的类型,*tid是一个指针变量,当创建一个thread成功后指针变量返回ID。
    const pthread_attr_t *attr:指定创建线程的属性,如线程优先级、初始栈大小、是否为守护进程等。可以使用NULL来使用默认值,通常情况下我们都是使用默认值。
    void *(*func) (void *):函数指针func,指定当新的线程创建之后,将执行的函数。
    void *arg:线程将执行的函数的参数。如果想传递多个参数,请将它们封装在一个结构体中。
    
    int pthread_join (pthread_t tid, void ** status);
    //用于等待某个线程退出,成功返回0,否则返回Exx。后面的参数,pthread_t tid是要等待的线程的ID,void ** status,发果不是NULL,那么线程的返回值存到status指向的空间中。(二级指针)
    
    pthread_t pthread_self (void);
    //pthread_self用于返回当时线程有ID,self嘛。
    
    int pthread_detach (pthread_t tid);
    //线程变为分离状态。分离状态的线程如果退出,就释放全部资源,如果退出,就可以调用pthread_join了。
    
    void pthread_exit (void *status);//线程终止,其它线程通过pthread_join获取该线程的返回值。

         在看例题时,总是会碰到  int main(int argc, char*argv[]]),一直不明白是什么意思,今天特意查了一下。 里面有两个形参,一个是argc,是命令行总的参数个数,一个是argv[ ]是保存命令行参数的字符串指针,其中第0个参数是程序的全名,以后的参数为命令行后面跟的用户输入的参数,argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。 指针数组的长度即为参数个数argc。数组元素初值由系统自动赋予。

举个例子:


 

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

 /*是否熟悉POSIX多线程编程技术?如熟悉,编写程序完成如下功能:

  1)有一int型全局变量g_Flag初始值为0;

  2)在主线称中起动线程1,打印“this is thread1”,并将g_Flag设置为1

  3)在主线称中启动线程2,打印“this is thread2”,并将g_Flag设置为2

  4)线程序1需要在线程2退出后才能退出

  5)主线程在检测到g_Flag从1变为2,或者从2变为1的时候退出

   */

typedef void* (*fun)(void*);

int g_Flag=0;

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

/*第四个要求,因为g_Flag是一个全局变量,线程thread1和thread2可以同时对它进行操作,

static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/*主线程main函数阻塞于等待g_Flag从1变为2,或者从2变为1。条件变量的相关函数如下:
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);
//Both return: 0 if OK, positive Exxx value on error
pthread_cond_wait用于等待某个特定的条件为真,pthread_cond_signal用于通知阻塞的线程某个特定的条件为真了。
通常条件变量与互斥锁一起使用。
*/

void* thread1(void*);
void* thread2(void*);

需要对它进行加锁保护,thread1和thread2要互斥访问才行,如何加锁保护——互斥锁。

互斥锁的相关操作函数如下:

int pthread_mutex_lock(pthread_mutex_t * mptr);

int pthread_mutex_unlock(pthread_mutex_t * mptr);

//Both return: 0 if OK, positive Exxx value on error

在对临界资源进行操作之前需要pthread_mutex_lock先加锁,操作完之后pthread_mutex_unlock再解锁。

而且在这之前需要声明一个pthread_mutex_t类型的变量,用作前面两个函数的参数。

*/

/*

 *  when program is started, a single thread is created, called the initial thread or main thread.

 *  Additional threads are created by pthread_create.

 *  So we just need to create two thread in main().

 */

int main(int argc, char** argv)

{

    printf("enter main\n");

    pthread_t tid1, tid2;

    int rc1=0, rc2=0;

    rc2 = pthread_create(&tid2, NULL, thread2, NULL);

    if(rc2 != 0)

        printf("%s: %d\n",__func__, strerror(rc2));

    rc1 = pthread_create(&tid1, NULL, thread1, &tid2);

    if(rc1 != 0)

        printf("%s: %d\n",__func__, strerror(rc1));

    pthread_cond_wait(&cond, &mutex);//等待,直到signal后才向下执行。

    //个人理解,条件变量和互斥锁发生了变化,才会释放掉这个函数,函数才能向下进行。

    printf("leave main\n");

    exit(0);    

}

/*

 * thread1() will be execute by thread1, after pthread_create()

 * it will set g_Flag = 1;

 */

void* thread1(void* arg)

{

    printf("enter thread1\n");

    printf("this is thread1, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());

    pthread_mutex_lock(&mutex);//上锁

    if(g_Flag == 2)

        pthread_cond_signal(&cond);//条件成立,因为flag发生了变化所以给wait一个信号

    g_Flag = 1;

    printf("this is thread1, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());

    pthread_mutex_unlock(&mutex);//解锁

    pthread_join(*(pthread_t*)arg, NULL);//

    printf("leave thread1\n");

    pthread_exit(0);

}

/*

 * thread2() will be execute by thread2, after pthread_create()

 * it will set g_Flag = 2;

 */

void* thread2(void* arg)

{

    printf("enter thread2\n");

    printf("this is thread2, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());

    pthread_mutex_lock(&mutex);//同上

    if(g_Flag == 1)

        pthread_cond_signal(&cond);

    g_Flag = 2;

    printf("this is thread2, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());

    pthread_mutex_unlock(&mutex);

    printf("leave thread2\n");

    pthread_exit(0);

}

二、ZMQ部分

  • 1、代码的开始处执行zmq_ctx_new(),在代码的最后一行执行zmq_ctx_destroy()..
  • 2、zmq_bind()的节点是一台服务器,它有一个公认的网络地址,而执行zmq_connect()的节点是一台客户机,它的地址要么是未知,要么是任意的。终端是指公认的网络地址。
  • 3、不存在zmq_accept()方法,当一个套接字被绑定到一个端点时,它自动地开始接受连接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值