首先先介绍一个无关的对象,可以用来获取毫秒级的时间。
有两个函数
int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv , const struct timezone *tz);
而timeval和timezone的结构体定义是这样的
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
举个栗子:
先声明一个timeval变量,struct timeval t_time;
然后直接调用函数即可
gettimeofday(&t_time, NULL);
---------------------------------------------------------------------------------------------------------------------------------
然后再说一个无关的东西,在g++编译运行的时候要记得带上-lpthread连接pthread.h库.
————————————————————————————————————————————
然后来说说多线程,多线程比较简单,就一个函数调用
pthread_t id;
if(pthread_create(&id, NULL, add_function, NULL)!=0)
{
perror("pthread_create");
exit(errno);
}
创建线程成功返回0,第一个参数是线程的id,第三个参数是线程运行的函数,函数类型是void* add_function(void *);
第四个参数为调用的函数所包含的参数。
另外注意的是不要忘记在进程运行的最后加一句pthread_exit(NULL)来阻塞进程,或者用pthread_join。。防止创建的线程还没结束,进程先结束了。
然后就是多线程的同步了,多线程可以用互斥锁来进行同步。
用pthread_mutex_t mutex来声明一个互斥锁。
然后用pthread_mutex_lock(&mutex)来获得锁
用pthread_mutex_unlock(&mutex)来释放锁
锁和一般的变量是不同的,加锁操作具有原子性,能保证线程之间的同步效果。
------------------------------------------------------------------------------------------------------------------------------------------------------------
最后说说多进程吧,多进程一般用到fork(),一次调用,两次返回结果,
比如int x = fork();
当返回值为0表示子进程,非0(一般返回子进行的进程id)则表示父进程。
另外要注意的是返回负数表示出现错误。
执行之后分成两个进程继续往下运行程序。假如是for (int x = 0, x < N; ++x) fork(); 则产生2^N - 1个进程,加上原来的init进程,一共2^N个。
产生了子进程之后代码段,数据段,堆栈都完全复制了父进程的,指向同一个物理地址,当进行一次读写操作之后则进行分离,指向不同的物理地址。各自有自己的生活。
多进程之间也有同步,也可以用互斥锁进行实现,不过比较麻烦,而且如果某个进程在获得了锁之后奔溃了(未释放锁),则其他进程会造成死锁,所以一般用文件锁。
互斥锁的使用如下。
值得注意的是,多进程因为分开之后内存是相对独立的。所以我们要把互斥锁放在共享内存里使用,然后再设置互斥锁的属性为PTHREAD_PROCESS_SHARED,使得可以在多进程多线程使用,默认属性是在一个进程的多线程使用的。
具体操作如下:
在共享内存中存在mutex锁。
然后在主进程下设置mutex的属性:
pthread_mutexattr_t attr; //属性变量 pthread_mutexattr_init(&attr); //初始化属性 //一定要设置为PTHREAD_PROCESS_SHARED //具体可以参考http://blog.chinaunix.NET/u/22935/showart_340408.html int ret = pthread_mutexattr_setpshared(&attr,PTHREAD_PROCESS_SHARED); // 设置属性变量为多进程使用 if( ret!=0 ) //返回错误 { perror("init_mutex pthread_mutexattr_setpshared"); exit(1); } pthread_mutex_init(&mutex, &attr); //将配置好的属性变量用于mutex的设置!!不要忘记这句了。然后这个互斥锁就能使用了。。
同样值得注意的是,多进程下,因为执行的顺序很难把握。所以一般在父进程加一句wait(&pid)来阻塞等待子进程结束返回pid。。
子进程在结束后释放了很多的资源,变成僵尸进程。只保留了类似“进程控制块”的东西,例如保留自己的进程id等信息。方便在父进程进行wait接收相关信息。。
另外用getpid()可以获得自身的进程id。。。用getppid可以获得父进程的进程id。。。
另外有两份测试用的代码,多线程和多进程。(在github上的test_time里有)。