linux条件锁

yiqingyang2012 2014-01-08 09:39:19
父线程里:
pthread_mutex_lock(&s_startupMutex);
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

printf("server_create_child_thread\n");
err = pthread_create(child_thread_value,&attr,child_thread,(void *)&peer );

while (child_thread_start == 0) {
printf("child_thread_start=0\n");
pthread_cond_wait(&s_startupCond, &s_startupMutex);
}
child_thread_start=0;
pthread_mutex_unlock(&s_startupMutex);

子线程里:
pthread_mutex_lock(&s_startupMutex);
sock_number = *(int *)sock_file_num;
child_thread_start = 1;
printf("broadcast\n");
pthread_cond_broadcast(&s_startupCond);
pthread_mutex_unlock(&s_startupMutex);
这里子线程明明广播了条件信号,为什么父线程还是一直阻塞等待呢,像是完全没有被唤醒
...全文
162 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiqingyang2012 2014-01-08
  • 打赏
  • 举报
回复
挺奇怪的,只是运行这几行代码是可以的,但放到我的工程里去就不行了,我在子线程里做了一些异步IO,子线程也发出信号了,结果一直阻塞在子线程里面,父线程完全接不到信号
非凡glj 2014-01-08
  • 打赏
  • 举报
回复
你直接把我给出的代码保存后编译试试
非凡glj 2014-01-08
  • 打赏
  • 举报
回复
子线程改成了以下代码,程序也是立即返回了

void *child_thread()
{
	pthread_mutex_lock(&s_startupMutex);
	child_thread_start = 1;
	printf("broadcast\n");
	pthread_cond_broadcast(&s_startupCond);
	pthread_mutex_unlock(&s_startupMutex);
	sleep(1000);
}
yiqingyang2012 2014-01-08
  • 打赏
  • 举报
回复
我不知道你这里是不是因为子线程退出了才唤醒的还是确实唤醒了。要不您试一下在子线程里用sleep函数休眠几秒钟,看是不是在子线程结束之前父线程被唤醒
yiqingyang2012 2014-01-08
  • 打赏
  • 举报
回复
果然可以了,是每一次include文件时,相当于在每隔.c里重新定义了这个变量。这细节点还真是没注意过,很感谢~~
非凡glj 2014-01-08
  • 打赏
  • 举报
回复
试了一下,能够唤醒阿,以下是根据楼主代码写的程序

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

pthread_cond_t s_startupCond;
pthread_mutex_t s_startupMutex;
int child_thread_start=0;

void *child_thread()
{
	pthread_mutex_lock(&s_startupMutex);
	child_thread_start = 1;
	printf("broadcast\n");
	pthread_cond_broadcast(&s_startupCond);
	pthread_mutex_unlock(&s_startupMutex);
}

int main()
{
	pthread_t child_thread_value;
	pthread_mutex_lock(&s_startupMutex);
	pthread_attr_t attr;
	pthread_attr_init (&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	printf("server_create_child_thread\n"); 
	int err = pthread_create(&child_thread_value,&attr,child_thread,(void *)NULL);

	while (child_thread_start == 0) {
		printf("child_thread_start=0\n");
		pthread_cond_wait(&s_startupCond, &s_startupMutex);
	}
        printf("pthread_cond_wait return and child_thread_start == 1\n");
	child_thread_start=0;
	pthread_mutex_unlock(&s_startupMutex);

    return 0;
}
以下是编译命令

gcc -o test test.c  -lpthread
以下是结果

server_create_child_thread
child_thread_start=0
broadcast
pthread_cond_wait return and child_thread_start == 1
非凡glj 2014-01-08
  • 打赏
  • 举报
回复
你的s_startupCond和s_startupMutex是不是定义在server.h里面的?这样主线程和子线程包含后使用的是不同的变量了,你在主线程的c文件里面定义,在子线程的c文件里面用extern引用试试
yiqingyang2012 2014-01-08
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> 
#include <string.h>
#include <netdb.h> 
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <pthread.h>
#include "../inc/server.h"
#define PORT        8999
#define MAXSIZE     (8 * 4096)
#define MAX_SOCK_CONNECTION 10

extern void *child_thread(void *sock_file_num );
int pipo_create();

char buf[1000];
int peer=0;
int s_fdWakeupRead;
int s_fdWakeupWrite;


int main(/*int argc, char *argv[]*/ )
{
    int sockfd, tmp_peer=0,err=0, len;
    struct sockaddr_in serv_addr, clnt_addr;
    char recvmsg[MAXSIZE], sendmsg[MAXSIZE]; 
    pthread_t ntid[MAX_SOCK_CONNECTION];
    int current_sock_connections=0;
        
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket error");
        return -1;
    }
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = inet_addr("172.19.1.28");//INADDR_ANY;
    bzero(&(serv_addr.sin_zero), 8);

    if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) < 0) {
        perror("bind err");
        return -1;
    }
 
    if (listen(sockfd, 4) < 0) {
        perror("listen error");
        return -1;
    }
    
    pipo_create();
    len = sizeof(clnt_addr);
    peer=0;
    do{
        printf("begin to accept\n");
        peer = accept(sockfd, (struct sockaddr *)&clnt_addr, &len);
        if (peer < 0) {
            perror("Server: accept failed.\n");
            continue;
        }
        printf("sucess get a socket connection,fd=%d\n",peer);
	
        if( current_sock_connections < MAX_SOCK_CONNECTION ){
          err = server_create_child_thread(peer, &ntid[current_sock_connections]);
	  
          if(err != 0){
            printf("can't create thread: %s\n",strerror(err));
            return 1;
          }
	  current_sock_connections++;
        }
        sleep(1);
        write(s_fdWakeupWrite,"pipo1\n",sizeof("pipo1\n"));
	printf("write to pipo\n");
        //pthread_join(ntid[current_sock_connections-1],NULL);
    }while (1) ;
    close(sockfd);
    return 0;
}

int pipo_create(){
  int filedes[2];

  pipe(filedes);
  s_fdWakeupRead = filedes[0];
  s_fdWakeupWrite = filedes[1];
}

int server_create_child_thread(int fd,pthread_t *child_thread_value){
  int err=0;
  
  pthread_mutex_lock(&s_startupMutex);
  pthread_attr_t attr;
  pthread_attr_init (&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	 
  printf("server_create_child_thread\n"); 
  err = pthread_create(child_thread_value,&attr,child_thread,(void *)NULL );

  while (child_thread_start == 0) {
    printf("child_thread_start=0\n");
    pthread_cond_wait(&s_startupCond, &s_startupMutex);
  }
  child_thread_start=0;

  pthread_mutex_unlock(&s_startupMutex);
  if(err ==0){
    printf("create child thread sucess\n");  
  }
  return err;
}
子线程:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> 
#include <string.h>
#include <netdb.h> 
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/select.h>
#include "../inc/server.h"
#include <signal.h>
#include <fcntl.h>
#define MAX_FILE_TYPE 10
#define MAX_BUFF_LEN 1000

int static sock_file_discription_type[MAX_FILE_TYPE];
int cur_sokt_conn = 0 ;

extern char buf[1000];
extern int s_fdWakeupRead;
extern int s_fdWakeupWrite;
extern int peer;

//extern static pthread_cond_t s_startupCond;

void child_thread_set_select_para(int wait_read_file_type);
int child_thread_read_from_con(int readable_file_type, char *read_buf);
int read_from_sock(int readable_file_type, char *read_buf);

  void sigHandler(int sig)
  {
     printf("network interupt"); 
  }
void *child_thread( ){
  printf("new thread\n");
  int sock_number;
  int rtn=0;
  int err=0;

  pthread_mutex_lock(&s_startupMutex);
  sock_number = peer;
  child_thread_start = 1;
  printf("broadcast\n");
  pthread_cond_broadcast(&s_startupCond);
  pthread_mutex_unlock(&s_startupMutex);
  close(sock_number);
基本上没什么区别
非凡glj 2014-01-08
  • 打赏
  • 举报
回复
这样的话你可以把你的工程的处理代码逐步屏蔽掉一些,直到能够收到信号为止,才好定位问题

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧