多进程与多线程与同步的故事

首先先介绍一个无关的对象,可以用来获取毫秒级的时间。

有两个函数

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里有)。










你可能感兴趣的:(Linux网络学习)