当前位置: 技术问答>linux和unix
linux 管道 线程同步
来源: 互联网 发布时间:2017-03-24
本文导语: 各位,最近想使用管道来实现线程同步,出现一个问题,百思不得其解,望各位大侠指点一二... 先贴上代码: #include #include #include #include #include #include #include int pip[] = {-1, -1}; void sleep_select(int i) { ...
各位,最近想使用管道来实现线程同步,出现一个问题,百思不得其解,望各位大侠指点一二...
先贴上代码:
这个程序中,主线程创建两个线程,一个线程向管道的写端写入数据,另一个线程监听管道的读端,当如果有数据到来时,读线程从管道中读出数据并打印。。
问题来了: 首先当我在写线程中,不用sleep()函数时,读端能监听到管道符的变化,当我用上sleep函数时,读端就监听不到管道符的变化了,我想知道这是为什么。。。。sleep()函数会影响管道符吗。。。。。
先贴上代码:
#include
#include
#include
#include
#include
#include
#include
int pip[] = {-1, -1};
void sleep_select(int i)
{
struct timeval timeout;
timeout.tv_sec = i;
timeout.tv_usec = 0;
select(0, NULL, NULL, NULL, &timeout);
}
static void *threadFunction(void* userdata)
{
char data[5] = {0};
fd_set fds;
struct timeval timeout = {1,0};
int ret;
FD_ZERO(&fds);
FD_SET(pip[0], &fds);
printf("p0: %dn", pip[0]);
printf("p1: %dn", pip[1]);
while (1)
{
ret = select(pip[0] + 1, &fds, NULL, NULL, &timeout);
if (ret 0)
{
read(pip[0], data, 5);
printf("data: %sn", data);
}
}
}
}
void *mysignal()
{
printf("signaln");
char data[] = "data";
while (1)
{
sleep_select(2);
//printf("sowelflsdfsldfsdlfsdln");
write(pip[1], data, 5);
}
}
int main(int argc, char* argv[])
{
char data[] = "data";
pthread_t id;
if (pipe(pip)) {
printf("pipe errorn");
exit(-1);
}
printf("p0: %dn", pip[0]);
printf("p1: %dn", pip[1]);
if (pthread_create(&id, NULL, threadFunction, NULL))
{
printf("create thread errorn");
exit(-1);
}
printf("pthread id = %un", id);
pthread_create(&id, NULL, mysignal, NULL);
//signal(SIGUSR1, mysignal);
while (1)
{
sleep_select(2);
//sleep(2);
//write(pip[1], data, 5);
}
pthread_join(id, NULL);
}
这个程序中,主线程创建两个线程,一个线程向管道的写端写入数据,另一个线程监听管道的读端,当如果有数据到来时,读线程从管道中读出数据并打印。。
问题来了: 首先当我在写线程中,不用sleep()函数时,读端能监听到管道符的变化,当我用上sleep函数时,读端就监听不到管道符的变化了,我想知道这是为什么。。。。sleep()函数会影响管道符吗。。。。。
|
哦,shit,需要把timeout的赋值移到while内!
#include
#include
#include
#include
#include
#include
#include
#include
//#include
int pip[2] = {-1, -1};
void sleep_select(int i)
{
struct timeval timeout;
timeout.tv_sec = i;
timeout.tv_usec = 0;
select(0, NULL, NULL, NULL, &timeout);
}
static void *threadFunction(void* userdata)
{
char data[6] = {0};
fd_set fds;
struct timeval timeout;
int ret;
FD_ZERO(&fds);
FD_SET(pip[0], &fds);
printf("p0: %dn", pip[0]);
printf("p1: %dn", pip[1]);
int counter = 0;
while (1)
{
timeout.tv_sec = 5;
timeout.tv_usec = 0;
//FD_ZERO(&fds);
FD_SET(pip[0], &fds);
ret = select(pip[0]+1, &fds, NULL, NULL, &timeout);
if (ret == -1)
{
printf("select errorn");
break;
}
else if (ret > 0)
{
if (FD_ISSET(pip[0], &fds))
{
read(pip[0], data, 5);
printf("data: %sn", data);
printf("%s: %d, [%s]n", __FUNCTION__, counter++, strerror(errno));
}
}
else
{
printf("no fd readyn");
}
}
return NULL;
}
void *mysignal()
{
printf("signaln");
char data[] = "data";
int counter = 0;
while (1)
{
sleep_select(2);
//sleep(2);
//printf("sowelflsdfsldfsdlfsdln");
write(pip[1], data, 5);
printf("time:%lu,%s: %d, [%s]n", time(NULL), __FUNCTION__, counter++, strerror(errno));
}
}
int main(int argc, char* argv[])
{
pthread_t id;
if (pipe(pip))
{
printf("pipe errorn");
exit(-1);
}
printf("p0: %dn", pip[0]);
printf("p1: %dn", pip[1]);
//fcntl(pip[0], F_SETFL, fcntl(pip[0], F_GETFL, 0) | O_NONBLOCK);
//fcntl(pip[1], F_SETFL, fcntl(pip[1], F_GETFL, 0) | O_NONBLOCK);
if (pthread_create(&id, NULL, threadFunction, NULL))
{
printf("create thread errorn");
exit(-1);
}
printf("pthread id = %lun", id);
pthread_create(&id, NULL, mysignal, NULL);
//signal(SIGUSR1, mysignal);
while (1)
{
sleep_select(2);
//sleep(2);
//write(pip[1], data, 5);
}
pthread_join(id, NULL);
}
|
select 不仅会改变timeout的值,而且会改变fd_set集合的值。所以调用完一次select后,fd_set和timeout都必须重置...
曾经因为这问题搞了很久。
曾经因为这问题搞了很久。